Exploratory Analysis
But before jumping right into the model building part, we first must
conduct a thorough exploratory analysis on the data we plan to work
with. In this portion of the report, we will be analyzing the weather
factor (precipitation and temperature), fixed effects (time of the day,
day of the week, delay distribution), and the temporal as well as the
spatial lags to see how the delays respond to each of these factors.
Weather
Since most of the NJ transit stations are in New Jersey state,
weather data from Newark Airport (EWR) is used. The following time
series plots displays the precipitation and temperature for each hour in
EWT during March 2018. The plots reveals a few days of
precipitation.
grid.arrange(
ggplot(weather.Panel, aes(interval60,Precipitation)) + geom_line() +
labs(title="Percipitation", x="Hour", y="Perecipitation") + plotTheme,
#ggplot(weather.Panel, aes(interval60,Wind_Speed)) + geom_line() +
#labs(title="Wind Speed", x="Hour", y="Wind Speed") + plotTheme,
ggplot(weather.Panel, aes(interval60,Temperature)) + geom_line() +
labs(title="Temperature", x="Hour", y="Temperature") + plotTheme,
top="Weather Data - EWR - March, 2018")

Describe and Explore the Data
The Time Series Plot below illustrate Bike share tripe per hours in
Jersey City. The skyblue line is used to visualize the Friday. In can
see the relatively high delay occur in mid-March.
merged_dataset%>%
dplyr::select(interval60, from, delay_minutes) %>%
gather(Variable, Value, -interval60, -from) %>%
group_by(Variable, interval60) %>%
summarize(Value = mean(Value))%>%
ggplot(aes(interval60, Value)) +
#geom_vline(data = monday, aes(xintercept = monday), color = "red") +
geom_vline(data = Friday, aes(xintercept = Friday), color = "skyblue") +
geom_line(size = 0.8,colour="darkblue")+
labs(title = "Delay distribution in A Month", subtitle = "NJ, March, 2018", x = "Day", y= "Mean Delay") +
theme_minimal()

plotTheme
Fixed effects
grid.arrange(ggplot(data = delay_day, aes(x = dotw, y = mean_delay)) +
geom_bar(stat = "identity",fill = "darkblue") +
labs(title = "Delay minutes in a week", x = "Day of The Week", y = "Mean Delay") +
theme_minimal(),
ggplot(data = delay_hour, aes(x = hour, y = mean_delay)) +
geom_bar(stat = "identity",fill = "darkblue") +
labs(title = "Delay minutes in 24 hours", x = "Hour in a day", y = "Mean Delay") +
theme_minimal(),
ggplot(data = delay_sequence, aes(x = stop_sequence, y = mean_delay)) +
geom_bar(stat = "identity",fill = "darkblue") +
labs(title = "Delay minutes in each sequence", x = "Stop Sequence", y = "Mean Delay") +
theme_minimal(),
ggplot(data = delay_time, aes(x = time_of_day, y = mean_delay)) +
geom_bar(stat = "identity",fill = "darkblue") +
labs(title = "Delay minutes in a week", x = "Day of The Week", y = "Mean Delay") +
theme_minimal(),
nrow=2)

The following time series plots display delay minutes in NJ Transit,
broken down by day of the week and by weekdays versus weekends. The data
shows a peak in delay minnutes on Sunday, with overall higher delay on
weekends compared to weekdays. This trend indicates that delay situation
is more commonly happen in weekend.
delay_week_hour <- merged_dataset %>%
group_by(weekend,hour(interval60))%>%
summarize(mean_delay = mean(delay_minutes))%>%
rename(hour = 'hour(interval60)')
ggplot(data = delay_week_hour, aes(x = hour, y = mean_delay, color = weekend)) +
geom_line() +
scale_color_manual(values = palette2) +
labs(title = "The delay under week and time", x = "Hour", y = "Delay Minutes") +
theme_minimal()

palette <- c(
"#1b9e77", # Teal green
"#d95f02", # Vibrant orange
"#7570b3", # Muted purple
"#e7298a", # Bright pink
"#66a61e", # Leaf green
"#e6ab02", # Golden yellow
"#a6761d" # Warm brown
)
delay_week_day <- merged_dataset %>%
group_by(dotw,hour(interval60))%>%
filter(!is.na(dotw)) %>%
summarize(mean_delay = mean(delay_minutes))%>%
rename(hour = 'hour(interval60)')
ggplot(data = delay_week_day, aes(x = hour, y = mean_delay, color = dotw)) +
geom_line() +
scale_color_manual(values = palette) +
labs(title = "The delay under week and time", x = "Hour", y = "Delay Minutes") +
theme_minimal()

The maps below illustrate the hourly delays by station. Weekends tend
to experience relatively higher delays compared to weekdays. Overall,
delayed stations appear to be spatially distributed in a random pattern,
without a clear clustering or specific geographic concentration.
ggplot() +
# Plot NJTracts as a base map
geom_sf(data = NJTracts %>%
st_transform(crs = 4326), color = "white") +
# Add points for bike share trips
geom_point(data = merged_dataset %>%
mutate(weekend = ifelse(dotw %in% c("Sun", "Sat"), "Weekend", "Weekday"),
time_of_day = case_when(
hour(interval60) < 7 | hour(interval60) > 19 ~ "Overnight",
hour(interval60) >= 7 & hour(interval60) < 10 ~ "AM Rush",
hour(interval60) >= 10 & hour(interval60) < 15 ~ "Mid-Day",
hour(interval60) >= 15 & hour(interval60) <= 19 ~ "PM Rush"
)) %>%
filter(!is.na(time_of_day)) %>%
group_by(from_id, from_lat, from_lon, weekend, time_of_day) %>%
summarize(mean_delay = mean(delay_minutes, na.rm = TRUE), .groups = "drop") %>%
ungroup(),
aes(x = from_lon, y = from_lat, color = mean_delay),
alpha = 0.9, size = 0.9) +
# Add color scale for mean delay
scale_colour_viridis(direction = -1, discrete = FALSE, option = "E") +
# Set axis limits
ylim(min(merged_dataset$from_lat), max(merged_dataset$from_lat)) +
xlim(min(merged_dataset$from_lon), max(merged_dataset$from_lon)) +
# Add facets for weekend and time of day
facet_grid(weekend ~ time_of_day) +
# Add labels and themes
labs(title = "delay min by station. NJ, march, 2018") +
theme_minimal() +
# Remove longitude and latitude from axes
theme(axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank()) +
theme_void()

The plot below displays an animated map of station delays, revealing
a relatively high frequency of delays in the northern area near
Manhattan, NY. This suggests that stations closer to Manhattan
experience more frequent delays, potentially due to higher traffic,
congestion, or operational complexity in this region.
delay_stop_time <- merged_dataset %>%
group_by(from,to,hour(interval60))%>%
summarize(mean_delay = mean(delay_minutes))%>%
rename(hour = 'hour(interval60)')%>%
left_join(stop,by=c('from'='STATION_ID'))%>%
st_as_sf(coords = c("LONGITUDE", "LATITUDE"), crs = 4326)
ggplot() +
geom_sf(data = NJTracts, color = 'white') +
geom_sf(data = delay_stop_time, aes(size = mean_delay,color = mean_delay),
fill = "transparent", alpha = 0.8) +
scale_colour_viridis(
name = "Mean delay", # Combined title for color and size
direction = -1,
option = "E",
discrete = FALSE
) +
scale_size_continuous(
name = "Mean delay", # Same title as color to combine legend
range = c(1, 5) # Adjust size range as needed
) +
guides(
color = guide_legend() # Use a single legend guide
) +
#scale_colour_viridis(direction = -1,discrete = FALSE, option = "D") +
labs(title = "Station Delay For One Day in March, 2018",
subtitle = "Hours in a day: {current_frame}") +
transition_manual(hour)+ mapTheme+theme_minimal()+ theme_void()

Temporal & Spatial lag
Creating Spatial and time lag variables capture the dependence of
phenomena on geospatial and time series, thereby improving the
predictive accuracy and explanatory power of the model. In practical
applications, these variables can help us better understand the dynamic
nature of delay and external influences.
The time lag variables considers how a phenomenon at one point in
time is affected by a previous point in time.
The following scatterplots present that Temporal lag has correlation
with the delay.
Short time lags (such as lag15min and lag30min) have a greater impact
on current delays and should be prioritized as features in the model.
However, Long-term lags (e.g., lag2h and lag3h) are less relevant but
still capture long-term delay trends.
# Prepare the data
scatter_data <- as.data.frame(ride.panel_min) %>%
group_by(interval15) %>%
summarise_at(vars(starts_with("lag"), "delay_minutes"), mean, na.rm = TRUE) %>%
gather(Variable, Value, -interval15, -delay_minutes) %>%
mutate(Variable = factor(Variable, levels = c("lag15min", "lag30min", "lag45min", "lag1h",
"lag1h15min", "lag1h30min", "lag1h45min", "lag2h", "lag2h15min",
"lag2h30min", "lag2h45min", "lag3h") )) %>%
filter(!is.na(Variable))
# Compute correlation values
correlations <- scatter_data %>%
group_by(Variable) %>%
summarize(correlation = round(cor(Value, delay_minutes, use = "complete.obs"), 2)) %>%
filter(!is.na(Variable))
# Create scatterplot
ggplot(scatter_data, aes(x = Value, y = delay_minutes)) +
geom_point(color = "grey20", alpha = 0.6, size = 1) + # Uniform color for points
geom_smooth(method = "lm", color = "red", se = FALSE, size = 0.5, linetype = "dashed") + # Best-fit line
facet_wrap(~Variable, scales = "free", nrow=2) + # Separate scatterplots for each Variable
labs(
title = "Scatterplot of Lag Variables vs Delay Minutes",
x = "Lag Value",
y = "Delay Minutes"
) +
theme_minimal() +
# Add correlation values as annotations
geom_text(
data = correlations,
aes(label = paste("r =", correlation), x = Inf, y = Inf),
hjust = 1.1, vjust = 1.2, inherit.aes = FALSE
)

Spatial lag variables consider how phenomena in one location are
affected by neighboring locations, especially in geographic space. The
following scatterplots indicate that spatial lag are very strong
correlation with the delay. However, the correlation are decreasing with
each additional lag stations, but the predictive power are stronger in
overall.
# Prepare the data
scatter_data_station <- as.data.frame(ride.panel_station) %>%
group_by(train_id) %>%
summarise_at(vars(starts_with("lags"), "delay_minutes"), mean, na.rm = TRUE) %>%
gather(Variable, Value, -train_id, -delay_minutes) %>%
mutate(Variable = factor(Variable, levels = c(
"lagsstation", "lags2station", "lags3station", "lags4station",
"lags5station", "lags6station", "lags7station", "lags8station"
)))
# Compute correlation values
correlations_station <- scatter_data_station %>%
group_by(Variable) %>%
summarize(correlation = round(cor(Value, delay_minutes, use = "complete.obs"), 2))
# Create scatterplot
ggplot(scatter_data_station, aes(x = Value, y = delay_minutes)) +
geom_point(color = "grey20", alpha = 0.6, size = 2) + # Uniform color for points
geom_smooth(method = "lm", color = "red", se = FALSE, size = 1, linetype = "dashed") + # Best-fit line
facet_wrap(~Variable, scales = "free", nrow=1) + # Separate scatterplots for each Variable
labs(
title = "Scatterplot of Station Lags vs Delay Minutes",
x = "Lag Value",
y = "Delay Minutes"
) +
xlim(0,25)+
ylim(0,25)+
theme_minimal() +
# Add correlation values as annotations
geom_text(
data = correlations_station,
aes(label = paste("r =", correlation), x = Inf, y = Inf),
hjust = 1.1, vjust = 1.2, inherit.aes = FALSE
)

Model
This section split data into a training and test set and develop a 3
week training set and a 2 week test set of all the stations. In the
following analysis, Three different linear regression are estimated on
delay.Train.
Since delays exhibit spatial and temporal correlations, incorporating
time and space features into the models can lead to improved
predictions. Additionally, variables such as the origin and destination
stations (from and to), whether it is a weekday or weekend, temperature,
precipitation, and stop sequence are also included to further enhance
the model’s accuracy.
- reg.30 (Predict delays within 30 minutes)
Shorter lag variables are used, such as lag45min, lag1h,
lag1h15min, etc. These lag variables correspond to the possible effects
in the target time range.
At the same time, lags3station, lags4station, lags5station, and
lags6station contain lagging site variables, indicating the propagation
of delay in space.
It is suitable for analyzing the prediction of delays in a
shorter time range (within 30 minutes).
- reg.60 (Forecast delay within 60 minutes)
Some lag variables of shorter time (such as lag45min) are
omitted, and more attention is paid to lag variables of more than 1
hour, such as lag1h30min, lag2h, lag2h30min, etc.
Simplified site lag variables, including only lags5station and
lags6station.
It is suitable for analyzing predictions of medium time range
(within 60 minutes) delays.
- reg.90 (Predict delays within 90 minutes)
Focus on longer time range lag variables, such as lag1h30min,
lag2h, lag3h, and remove short time lag variables (such as
lag45min).
Only one site lag variable, lags6station, is retained.
Suitable for analyzing predictions of long time ranges (within 90
minutes).
delay.Train <- filter(ride.panel_station, week <= 11)
delay.Test <- filter(ride.panel_station, week > 11)
reg.30 <-
lm(delay_minutes ~ from + to + weekend + Temperature + Precipitation + lag45min
+ lag1h + lag1h15min + lag1h30min + lag1h45min + lag2h + lag2h15min + lag2h30min +
lag2h45min + lag3h
+ lags3station+ lags4station+ lags5station + stop_sequence ,
data=delay.Train)
reg.60 <-
lm(delay_minutes ~ from + to + weekend + Temperature + Precipitation
+ lag1h + lag1h15min + lag1h30min + lag1h45min + lag2h + lag2h15min + lag2h30min + lag2h45min + lag3h + lags5station + lags6station + stop_sequence ,
data=delay.Train)
reg.90 <-
lm(delay_minutes ~ from + to + weekend + Temperature + Precipitation
+ lag1h30min + lag1h45min + lag2h + lag2h15min + lag2h30min + lag2h45min + lag3h+ lags6station + stop_sequence ,
data=delay.Train)
delay.Test.weekNest <-
delay.Test %>%
nest(-week)
model_pred <- function(dat, fit){
pred <- predict(fit, newdata = dat)}
The Bar charts below illustrates the MAE values for the Three models.
It displays the highest MAE value in the 90 min delay model, and the
lowest MAE value in the 30-min delay model. This indicates that the
30-minute model is the most accurate among the three.
week_predictions <-
delay.Test.weekNest %>%
mutate(mod.30 = map(.x = data, fit = reg.30, .f = model_pred),
mod.60 = map(.x = data, fit = reg.60, .f = model_pred),
mod.90 = map(.x = data, fit = reg.90, .f = model_pred),
) %>%
gather(Regression, Prediction, -data, -week) %>%
mutate(Observed = map(data, pull, delay_minutes),
Absolute_Error = map2(Observed, Prediction, ~ abs(.x - .y)),
MAE = map_dbl(Absolute_Error, mean, na.rm = TRUE),
sd_AE = map_dbl(Absolute_Error, sd, na.rm = TRUE))
week_predictions %>%
dplyr::select(week, Regression, MAE) %>%
gather(Variable, MAE, -Regression, -week) %>%
ggplot(aes(week, MAE)) +
geom_bar(aes(fill = Regression), position = "dodge", stat="identity") +
scale_fill_manual(values = palette5) +
labs(title = "Mean Absolute Errors by model specification and week") +
plotTheme

The time series plot below shows the predicted and observed mean
delay. Overall, the models tend to under-predict the observed values.
Among all regression models, the 30-minute model is the most accurate,
closely capturing the observed delay patterns. The longer time
prediction (such as 60 and 90 min model) typically introduce greater
uncertainty, so the accuracy decrease while the prediction horizon
increases (60 and 90 minutes).
delay.Test_5 <- delay.Test %>%
mutate(pre_5 = predict(reg.30, newdata = delay.Test),
abosulte_error = abs(pre_5 - delay_minutes),
MAE = mean(abosulte_error, na.rm = TRUE),
sd_AE = sd(abosulte_error, na.rm = TRUE),
per_error = (pre_5 - delay_minutes) / delay_minutes,
per_error = ifelse(per_error == Inf, 0, per_error),
per_error = ifelse(per_error == -Inf, 0, per_error)) %>%
rename(mod_30 = pre_5)
delay.Test_6 <- delay.Test%>%
mutate(pre_6 = predict(reg.60, newdata = delay.Test),
abosulte_error = abs(pre_6 - delay_minutes),
MAE = mean(abosulte_error,na.rm = TRUE),
sd_AE = sd(abosulte_error,na.rm = TRUE),
per_error = (pre_6 - delay_minutes)/delay_minutes,
per_error = ifelse(per_error == Inf,0,per_error),
per_error = ifelse(per_error == -Inf,0,per_error))%>%
rename(mod_60 = pre_6)
delay.Test_7 <- delay.Test%>%
mutate(pre_7 = predict(reg.90, newdata = delay.Test),
abosulte_error = abs(pre_7 - delay_minutes),
MAE = mean(abosulte_error,na.rm = TRUE),
sd_AE = sd(abosulte_error,na.rm = TRUE),
per_error = (pre_7 - delay_minutes)/delay_minutes,
per_error = ifelse(per_error == Inf,0,per_error),
per_error = ifelse(per_error == -Inf,0,per_error))%>%
rename(mod_90 = pre_7)
grid.arrange(
delay.Test_5 %>%
dplyr::select(interval60, from, delay_minutes, mod_30) %>%
gather(Variable, Value, -interval60, -from) %>%
group_by(Variable, interval60) %>%
summarize(Value = mean(Value, na.rm = TRUE), .groups = "drop") %>%
ggplot(aes(interval60, Value, colour = Variable)) +
geom_line(size = 0.9) +
labs(
title = "Predicted/Observed Delay Time Series",
subtitle = "30 Minutes Pre-Predict",
x = "Day",
y = "Mean Delay"
) +
theme_minimal(),
delay.Test_6 %>%
dplyr::select(interval60, from, delay_minutes, mod_60) %>%
gather(Variable, Value, -interval60, -from) %>%
group_by(Variable, interval60) %>%
summarize(Value = mean(Value, na.rm = TRUE), .groups = "drop") %>%
ggplot(aes(interval60, Value, colour = Variable)) +
geom_line(size = 0.9) +
labs(
title = "Predicted/Observed Delay Time Series",
subtitle = "60 Minutes Pre-Predict",
x = "Day",
y = "Mean Delay"
) +
theme_minimal(),
delay.Test_7 %>%
dplyr::select(interval60, from, delay_minutes, mod_90) %>%
gather(Variable, Value, -interval60, -from) %>%
group_by(Variable, interval60) %>%
summarize(Value = mean(Value, na.rm = TRUE), .groups = "drop") %>%
ggplot(aes(interval60, Value, colour = Variable)) +
geom_line(size = 0.9) +
labs(
title = "Predicted/Observed Delay Time Series",
subtitle = "90 Minutes Pre-Predict",
x = "Day",
y = "Mean Delay"
) +
theme_minimal(),
ncol=1)

The maps below present the MAE (Mean Absolute Error) values for three
different models. As observed, the southern stations exhibit relatively
higher MAE values compared to other regions, indicating greater
prediction errors in these areas. Moreover, the maps below that still
illustrates the 30-min model is the most accurate predictions, with
smaller and more localized errors.
# Combine the data for all models into one data frame
all_models_data <- week_predictions %>%
mutate(interval15 = map(data, pull, interval15),
from_id = map(data, pull, from_id),
from_lat = map(data, pull, from_lat),
from_lon = map(data, pull, from_lon)) %>%
select(interval15, from_id, from_lon, from_lat, Observed, Prediction, Regression) %>%
unnest() %>%
filter(Regression %in% c("mod.30", "mod.60", "mod.90")) %>% # Include only the models of interest
group_by(from_id, from_lon, from_lat, Regression) %>%
summarize(MAE = mean(abs(Observed - Prediction), na.rm = TRUE), .groups = "drop") %>%
mutate(Model = case_when(
Regression == "mod.30" ~ "30 min",
Regression == "mod.60" ~ "60 min",
Regression == "mod.90" ~ "90 min"
))
# Plot with facet_wrap
ggplot(all_models_data) +
geom_sf(data = NJ_Census, color = "grey50", fill = "grey70") +
geom_point(aes(x = from_lon, y = from_lat, color = MAE),
fill = "transparent", alpha = 0.8) +
scale_color_gradientn(name = "Mean Absolute Error", colors = c("lightyellow", "red")) +
facet_wrap(~Model) +
ylim(min(merged_dataset$from_lat), max(merged_dataset$from_lat)) +
xlim(min(merged_dataset$from_lon), max(merged_dataset$from_lon)) +
labs(title = "Mean Absolute Error by Model") +
mapTheme

The maps below display the distribution of MAE values for NJ transit
stations during different time periods on weekdays and weekends using
the 30-minute model. Overall, weekends exhibit relatively higher MAE
values compared to weekdays. Meanwhile, the model performs better during
weekdays, as indicated by lower MAE values across most stations and time
periods.
week_predictions %>%
mutate(interval60 = map(data, pull, interval60),
from_id = map(data, pull, from_id),
from_lat = map(data, pull, from_lat),
from_lon = map(data, pull, from_lon),
dotw = map(data, pull, dotw)) %>%
select(interval60, from_id, from_lon,
from_lat, Observed, Prediction, Regression,
dotw) %>%
unnest() %>%
filter(Regression == "mod.30")%>%
mutate(weekend = ifelse(dotw %in% c("Sun", "Sat"), "Weekend", "Weekday"),
time_of_day = case_when(hour(interval60) < 7 | hour(interval60) > 18 ~ "Overnight",
hour(interval60) >= 7 & hour(interval60) < 10 ~ "AM Rush",
hour(interval60) >= 10 & hour(interval60) < 15 ~ "Mid-Day",
hour(interval60) >= 15 & hour(interval60) <= 18 ~ "PM Rush")) %>%
group_by(from_id, weekend, time_of_day, from_lon, from_lat) %>%
summarize(MAE = mean(abs(Observed-Prediction), na.rm = TRUE))%>%
ggplot(.)+
geom_sf(data = NJ_Census, color = "white")+
geom_point(aes(x = from_lon, y = from_lat, color = MAE),
fill = "transparent", alpha = 0.5, size = 3) +
scale_colour_viridis(direction = -1,
discrete = FALSE, option = "E") +
ylim(min(dat_census$from_lat), max(dat_census$from_lat))+
xlim(min(dat_census$from_lon), max(dat_census$from_lon))+
facet_grid(weekend~time_of_day)+
labs(title="Mean Absolute Errors, 30 min Model")+
mapTheme

LS0tCnRpdGxlOiAiRm9yZWNhc3QgTWV0cm8gdHJhaW4gZGVsYXlzIGluIGFuZCBhcm91bmQgTllDIgpkYXRlOiAiMjAyNC0xMi0xMiIKYXV0aG9yOiBKaWF0b25nIFN1LCBSdW5DaHVhbmcgTWEKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogc2ltcGxleAogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBwcm9ncmVzczogaGlkZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICBwYXJhbXM6CiAgaW5jbHVkZV93YXJuaW5nczogZmFsc2UgICMgQWRkIHRoaXMgbGluZSB0byBzdXBwcmVzcyB3YXJuaW5ncwotLS0KCiMgSW50cm9kdWN0aW9uCgpUcmFpbiBkZWxheXMgY2FuIHNpZ25pZmljYW50bHkgaW1wYWN0IHRoZSBlZmZpY2llbmN5IG9mIHVyYmFuIHRyYW5zaXQgc3lzdGVtcyBieSBhZmZlY3RpbmcgcGFzc2VuZ2Vyc+KAmSBzY2hlZHVsZXMgZXNwZWNpYWxseSBhcm91bmQgbGFyZ2UgbWV0cm9wb2xpdGFucyBsaWtlIE5ldyBZb3JrIENpdHkgd2hlcmUgYSBsYXJnZSBwb3J0aW9uIG9mIHBlb3BsZSByZWxpZXMgb24gdHJhaW5zIGZvciBjb21tdXRlLiBIb3dldmVyLCBpZiB3ZSBjYW4gYmUgaW5mb3JtZWQgb2YgdGhlIGRlbGF5cyBhaGVhZCBvZiB0aW1lLCB0aGUgY2hhbmNlcyB0aGF0IHRoZXkgd2lsbCBhZmZlY3Qgb3VyIHRyYXZlbHMgd2lsbCBiZSBtdWNoIGxvd2VyLiBUaGVyZWZvcmUsIGhhdmluZyBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mIGFuZCBiZWluZyBhYmxlIHRvIHByZWRpY3QgdGhlc2UgcG90ZW50aWFsIGRlbGF5cyBpcyBjcnVjaWFsIGZvciB0aGUgaGVhbHRoIG9mIGFuIHVyYmFuIHRyYW5zaXQgc3lzdGVtLiBJbiB0aGlzIHN0dWR5LCB3ZSB3aWxsIGJlIHVzaW5nIGEgZGF0YXNldCB0aGF0IHJlY29yZHMgdHJhaW4gZGVsYXkgZGF0YSBvZiBOSiBUcmFuc2l0IGFuZCBBbXRyYWsgcmFpbHMgZnJvbSAyMDE4IHRvIDIwMjAgdG8gY29uZHVjdCBvdXIgZXhwbG9yYXRvcnkgYW5hbHlzaXMgYW5kIGJ1aWxkIHByZWRpY3RpdmUgbW9kZWxzLiBBIHByb3Bvc2FsIGZvciBhIG1vYmlsZSBhcHBsaWNhdGlvbiB3aWxsIGFsc28gYmUgcHJlc2VudGVkIHRvIG1ha2UgdGhlIHRlY2huaWNhbCBtb2RlbCBhY2Nlc3NpYmxlIGZvciBldmVyeWRheSBwYXNzZW5nZXJzIHdobyBuZWVkIGl0IHRoZSBtb3N0LgoKLSAgIFBsZWFzZSBjaGVjayB0aGUgW3ZpZGVvIHByZXNlbnRhdGlvbl0oaHR0cHM6Ly95b3V0dS5iZS8zYmd4N2NMb2ZtSSkgaGVyZS4KCmBgYHtyIHNldHVwLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeSh0aWdyaXMpCmxpYnJhcnkodGlkeWNlbnN1cykKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KHJpZW0pCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZW9zcGhlcmUpCmxpYnJhcnkoZ2dhbmltYXRlKQoKCnBsb3RUaGVtZSA8LSB0aGVtZSgKICBwbG90LnRpdGxlID1lbGVtZW50X3RleHQoc2l6ZT0xMiksCiAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLAogIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLAogIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgIyBTZXQgdGhlIGVudGlyZSBjaGFydCByZWdpb24gdG8gYmxhbmsKICBwYW5lbC5iYWNrZ3JvdW5kPWVsZW1lbnRfYmxhbmsoKSwKICBwbG90LmJhY2tncm91bmQ9ZWxlbWVudF9ibGFuaygpLAogICNwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG91cj0iI0YwRjBGMCIpLAogICMgRm9ybWF0IHRoZSBncmlkCiAgcGFuZWwuZ3JpZC5tYWpvcj1lbGVtZW50X2xpbmUoY29sb3VyPSIjRDBEMEQwIixzaXplPS4yKSwKICBheGlzLnRpY2tzPWVsZW1lbnRfYmxhbmsoKSkKCm1hcFRoZW1lIDwtIHRoZW1lKHBsb3QudGl0bGUgPWVsZW1lbnRfdGV4dChzaXplPTEyKSwKICAgICAgICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgpLAogICAgICAgICAgICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLAogICAgICAgICAgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQ9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yPWVsZW1lbnRfbGluZShjb2xvdXIgPSAndHJhbnNwYXJlbnQnKSwKICAgICAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5taW5vcj1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiLCAKICAgICAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICAgICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMSwgMSwgMSwgMSwgJ2NtJyksCiAgICAgICAgICAgICAgICAgIGxlZ2VuZC5rZXkuaGVpZ2h0ID0gdW5pdCgxLCAiY20iKSwgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMC4yLCAiY20iKQogICAgICAgICAgICAgICAgICApCgpwYWxldHRlNSA8LSBjKCIjZWZmM2ZmIiwiI2JkZDdlNyIsIiM2YmFlZDYiLCIjMzE4MmJkIiwiIzA4NTE5YyIpCnBhbGV0dGU0IDwtIGMoIiNEMkZCRDQiLCIjOTJCQ0FCIiwiIzUyN0Q4MiIsIiMxMjNGNUEiKQpwYWxldHRlMiA8LSBjKCIjNmJhZWQ2IiwiIzA4NTE5YyIpCnBhbGV0dGU3IDwtIGMoInJlZCIsICJibHVlIiwgImdyZWVuIiwgIm9yYW5nZSIsICJwdXJwbGUiLCAieWVsbG93IiwgInBpbmsiKQoKCnRpZHljZW5zdXM6OmNlbnN1c19hcGlfa2V5KCJlNzlmMzcwNmI2ZDYxMjQ5OTY4YzZjZTg4Nzk0ZjZmNTU2ZTViZjNkIiwgb3ZlcndyaXRlID0gVFJVRSkKCm5qdHJhbnNpdCA8LSByZWFkX2NzdigiL1VzZXJzL2ppYXRvbmcvRGVza3RvcC8yMDE4XzAzLmNzdiIpIAoKYGBgCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0Kc3RvcCA8LSBzdF9yZWFkKCJodHRwczovL3NlcnZpY2VzNi5hcmNnaXMuY29tL00wdDBIUEU1M3BGSzUyNVUvYXJjZ2lzL3Jlc3Qvc2VydmljZXMvTkpUcmFuc2l0X1JhaWxfU3RhdGlvbnMvRmVhdHVyZVNlcnZlci8wL3F1ZXJ5P291dEZpZWxkcz0qJndoZXJlPTElM0QxJmY9Z2VvanNvbiIpICU+JQogIG11dGF0ZShTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ0F0bGFudGljIENpdHknLCAnQXRsYW50aWMgQ2l0eSBSYWlsIFRlcm1pbmFsJywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoKFNUQVRJT05fSUQgPT0gJ01pZGRsZXRvd24nKSYoQ09VTlRZID09ICdPcmFuZ2UsIE5ZJyksICdNaWRkbGV0b3duIE5ZJywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnUHJpbmNldG9uIEpjdC4nLCAnUHJpbmNldG9uIEp1bmN0aW9uJywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnU2VjYXVjdXMgSnVuY3Rpb24gVXBwZXIgTGV2ZWwnLCAnU2VjYXVjdXMgVXBwZXIgTHZsJywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnQW5kZXJzb24gU3RyZWV0LUhhY2tlbnNhY2snLCAnQW5kZXJzb24gU3RyZWV0JywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnQmF5IFN0cmVldC1Nb250Y2xhaXInLCAnQmF5IFN0cmVldCcsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ0Jyb2Fkd2F5JywgJ0Jyb2Fkd2F5IEZhaXIgTGF3bicsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ0Vzc2V4IFN0cmVldC1IYWNrZW5zYWNrJywgJ0Vzc2V4IFN0cmVldCcsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ0dsZW4gUm9jay1Cb3JvIEhhbGwnLCAnR2xlbiBSb2NrIEJvcm8gSGFsbCcsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ0dsZW4gUm9jay1NYWluJywgJ0dsZW4gUm9jayBNYWluIExpbmUnLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdIb2Jva2VuIFRlcm1pbmFsJywgJ0hvYm9rZW4nLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZSgoU1RBVElPTl9JRCA9PSAnTWlkZGxldG93bicpJihDT1VOVFkgPT0gJ01vbm1vdXRoJyksICdNaWRkbGV0b3duIE5KJywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnTW9udGNsYWlyIFN0IFVuaXYnLCAnTW9udGNsYWlyIFN0YXRlIFUnLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdNb3VudGFpbiBWaWV3LVdheW5lJywgJ01vdW50YWluIFZpZXcnLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdQZW5uc2F1a2VuIFRyYW5zaXQgQ2VudGVyJywgJ1Blbm5zYXVrZW4nLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdSYWRidXJuJywgJ1JhZGJ1cm4gRmFpciBMYXduJywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnUmFtc2V5JywgJ1JhbXNleSBNYWluIFN0JywgU1RBVElPTl9JRCksCiAgICAgICAgIFNUQVRJT05fSUQgPSBpZmVsc2UoU1RBVElPTl9JRCA9PSAnUnRlIDE3IFJhbXNleScsICdSYW1zZXkgUm91dGUgMTcnLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdTZWNhdWN1cyBKdW5jdGlvbiBMb3dlciBMZXZlbCcsICdTZWNhdWN1cyBMb3dlciBMdmwnLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdUZXRlcmJvcm8tV2lsbGlhbXMgQXZlJywgJ1RldGVyYm9ybycsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ1dhdHNlc3NpbmcnLCAnV2F0c2Vzc2luZyBBdmVudWUnLCBTVEFUSU9OX0lEKSwKICAgICAgICAgU1RBVElPTl9JRCA9IGlmZWxzZShTVEFUSU9OX0lEID09ICdXYXluZSBSb3V0ZSAyMyBUcmFuc2l0IENlbnRlcicsICdXYXluZS1Sb3V0ZSAyMycsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJ1dvb2QtUmlkZ2UnLCAnV29vZCBSaWRnZScsIFNUQVRJT05fSUQpLAogICAgICAgICBTVEFUSU9OX0lEID0gaWZlbHNlKFNUQVRJT05fSUQgPT0gJzMwdGggU3RyZWV0IFN0YXRpb24nLCAnUGhpbGFkZWxwaGlhJywgU1RBVElPTl9JRCksCiAgICAgICAgIGxpbmVfaW50ZXJzY3QgPSBzdHJfY291bnQoUkFJTF9TRVJWSUNFLCAiLCIpICsgMSklPiUKICBkcGx5cjo6c2VsZWN0KFNUQVRJT05fSUQsTEFUSVRVREUsTE9OR0lUVURFLGxpbmVfaW50ZXJzY3QpJT4lCiAgc3RfZHJvcF9nZW9tZXRyeSgpCgpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQptZXJnZWRfZGF0YXNldCA8LSBtZXJnZShuanRyYW5zaXQsIHN0b3AsIGJ5LnggPSAiZnJvbSIsIGJ5LnkgPSAiU1RBVElPTl9JRCIsYWxsLnggPSBUUlVFKSAKIyBtZXJnZSBmcm9tIAptZXJnZWRfZGF0YXNldCA8LSBtZXJnZShtZXJnZWRfZGF0YXNldCwgc3RvcCwgYnkueCA9ICJ0byIsIGJ5LnkgPSAiU1RBVElPTl9JRCIsYWxsLnggPSBUUlVFKSAKIyBtZXJnZSB0bwoKbWVyZ2VkX2RhdGFzZXQgPC0gbWVyZ2VkX2RhdGFzZXQlPiUKICBmaWx0ZXIodG8gIT0gJ01vdW50IEFybGluZ3RvbicpJT4lCiAgZmlsdGVyKGZyb20gIT0gJ01vdW50IEFybGluZ3RvbicpJT4lCiAgcmVuYW1lKGZyb21fbGF0ID0gTEFUSVRVREUueCwKICAgICAgICAgZnJvbV9sb24gPSBMT05HSVRVREUueCwKICAgICAgICAgZnJvbV9pbnRlciA9IGxpbmVfaW50ZXJzY3QueCwKICAgICAgICAgdG9fbGF0ID0gTEFUSVRVREUueSwKICAgICAgICAgdG9fbG9uID0gTE9OR0lUVURFLnksCiAgICAgICAgIHRvX2ludGVyID0gbGluZV9pbnRlcnNjdC55CiAgICAgICAgICklPiUKICBtdXRhdGUoZGlzdGFuY2UgPSBkaXN0SGF2ZXJzaW5lKGNiaW5kKGZyb21fbG9uLCBmcm9tX2xhdCksIGNiaW5kKHRvX2xvbiwgdG9fbGF0KSksCiAgICAgICAgIGludGVydmFsNjAgPSBmbG9vcl9kYXRlKHltZF9obXMoc2NoZWR1bGVkX3RpbWUpLCB1bml0ID0gImhvdXIiKSwKICAgICAgICAgd2VlayA9IHdlZWsoaW50ZXJ2YWw2MCksCiAgICAgICAgIGRvdHcgPSB3ZGF5KGludGVydmFsNjAsIGxhYmVsPVRSVUUpLAogICAgICAgICB0aW1lX29mX2RheSA9IGNhc2Vfd2hlbihob3VyKGludGVydmFsNjApIDwgNyB8IGhvdXIoaW50ZXJ2YWw2MCkgPiAxOSB+ICJPdmVybmlnaHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyKGludGVydmFsNjApID49IDcgJiBob3VyKGludGVydmFsNjApIDwgMTAgfiAiQU0gUnVzaCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIoaW50ZXJ2YWw2MCkgPj0gMTAgJiBob3VyKGludGVydmFsNjApIDwgMTUgfiAiTWlkLURheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIoaW50ZXJ2YWw2MCkgPj0gMTUgJiBob3VyKGludGVydmFsNjApIDw9IDE5IH4gIlBNIFJ1c2giKSwKICAgICAgICAgd2Vla2VuZCA9IGlmZWxzZShkb3R3ICVpbiUgYygiU3VuIiwgIlNhdCIpLCAiV2Vla2VuZCIsICJXZWVrZGF5IikpIAoKCmBgYAoKIyBFeHBsb3JhdG9yeSBBbmFseXNpcwoKQnV0IGJlZm9yZSBqdW1waW5nIHJpZ2h0IGludG8gdGhlIG1vZGVsIGJ1aWxkaW5nIHBhcnQsIHdlIGZpcnN0IG11c3QgY29uZHVjdCBhIHRob3JvdWdoIGV4cGxvcmF0b3J5IGFuYWx5c2lzIG9uIHRoZSBkYXRhIHdlIHBsYW4gdG8gd29yayB3aXRoLiBJbiB0aGlzIHBvcnRpb24gb2YgdGhlIHJlcG9ydCwgd2Ugd2lsbCBiZSBhbmFseXppbmcgdGhlIHdlYXRoZXIgZmFjdG9yIChwcmVjaXBpdGF0aW9uIGFuZCB0ZW1wZXJhdHVyZSksIGZpeGVkIGVmZmVjdHMgKHRpbWUgb2YgdGhlIGRheSwgZGF5IG9mIHRoZSB3ZWVrLCBkZWxheSBkaXN0cmlidXRpb24pLCBhbmQgdGhlIHRlbXBvcmFsIGFzIHdlbGwgYXMgdGhlIHNwYXRpYWwgbGFncyB0byBzZWUgaG93IHRoZSBkZWxheXMgcmVzcG9uZCB0byBlYWNoIG9mIHRoZXNlIGZhY3RvcnMuCgojIyBXZWF0aGVyCgpTaW5jZSBtb3N0IG9mIHRoZSBOSiB0cmFuc2l0IHN0YXRpb25zIGFyZSBpbiBOZXcgSmVyc2V5IHN0YXRlLCB3ZWF0aGVyIGRhdGEgZnJvbSBOZXdhcmsgQWlycG9ydCAoRVdSKSBpcyB1c2VkLiBUaGUgZm9sbG93aW5nIHRpbWUgc2VyaWVzIHBsb3RzIGRpc3BsYXlzIHRoZSBwcmVjaXBpdGF0aW9uIGFuZCB0ZW1wZXJhdHVyZSBmb3IgZWFjaCBob3VyIGluIEVXVCBkdXJpbmcgTWFyY2ggMjAxOC4gVGhlIHBsb3RzIHJldmVhbHMgYSBmZXcgZGF5cyBvZiBwcmVjaXBpdGF0aW9uLgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CndlYXRoZXIuUGFuZWwgPC0gCiAgcmllbV9tZWFzdXJlcyhzdGF0aW9uID0gIkVXUiIsIGRhdGVfc3RhcnQgPSAiMjAxOC0wMy0wMSIsIGRhdGVfZW5kID0gIjIwMTgtMDMtMzEiKSAlPiUKICBkcGx5cjo6c2VsZWN0KHZhbGlkLCB0bXBmLCBwMDFpLCBza250KSU+JQogIHJlcGxhY2UoaXMubmEoLiksIDApICU+JQogICAgbXV0YXRlKGludGVydmFsNjAgPSB5bWRfaChzdWJzdHIodmFsaWQsMSwxMykpKSAlPiUKICAgIG11dGF0ZSh3ZWVrID0gd2VlayhpbnRlcnZhbDYwKSwKICAgICAgICAgICBkb3R3ID0gd2RheShpbnRlcnZhbDYwLCBsYWJlbD1UUlVFKSkgJT4lCiAgICBncm91cF9ieShpbnRlcnZhbDYwKSAlPiUKICAgIHN1bW1hcml6ZShUZW1wZXJhdHVyZSA9IG1heCh0bXBmKSwKICAgICAgICAgICAgICBQcmVjaXBpdGF0aW9uID0gc3VtKHAwMWkpLAogICAgICAgICAgICAgIFdpbmRfU3BlZWQgPSBtYXgoc2tudCkpICU+JQogICAgbXV0YXRlKFRlbXBlcmF0dXJlID0gaWZlbHNlKFRlbXBlcmF0dXJlID09IDAsIDQyLCBUZW1wZXJhdHVyZSkpCgpnbGltcHNlKHdlYXRoZXIuUGFuZWwpCgpgYGAKCmBgYHtyfQpncmlkLmFycmFuZ2UoCiAgZ2dwbG90KHdlYXRoZXIuUGFuZWwsIGFlcyhpbnRlcnZhbDYwLFByZWNpcGl0YXRpb24pKSArIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZT0iUGVyY2lwaXRhdGlvbiIsIHg9IkhvdXIiLCB5PSJQZXJlY2lwaXRhdGlvbiIpICsgcGxvdFRoZW1lLAogICNnZ3Bsb3Qod2VhdGhlci5QYW5lbCwgYWVzKGludGVydmFsNjAsV2luZF9TcGVlZCkpICsgZ2VvbV9saW5lKCkgKyAKICAgICNsYWJzKHRpdGxlPSJXaW5kIFNwZWVkIiwgeD0iSG91ciIsIHk9IldpbmQgU3BlZWQiKSArIHBsb3RUaGVtZSwKICBnZ3Bsb3Qod2VhdGhlci5QYW5lbCwgYWVzKGludGVydmFsNjAsVGVtcGVyYXR1cmUpKSArIGdlb21fbGluZSgpICsgCiAgICBsYWJzKHRpdGxlPSJUZW1wZXJhdHVyZSIsIHg9IkhvdXIiLCB5PSJUZW1wZXJhdHVyZSIpICsgcGxvdFRoZW1lLAogIHRvcD0iV2VhdGhlciBEYXRhIC0gRVdSIC0gTWFyY2gsIDIwMTgiKQpgYGAKCiMjIERlc2NyaWJlIGFuZCBFeHBsb3JlIHRoZSBEYXRhCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KIyBjZW5zdXMgZGF0YQpOSl9DZW5zdXMgPC0gCiAgZ2V0X2FjcyhnZW9ncmFwaHkgPSAiY291bnR5IHN1YmRpdmlzaW9uIiwgCiAgICAgICAgICB2YXJpYWJsZXMgPSBjKCJCMDEwMDNfMDAxIiwgIkIxOTAxM18wMDEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIkIwMjAwMV8wMDIiLCAiQjA4MDEzXzAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJCMDgwMTJfMDAxIiwgIkIwODMwMV8wMDEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIkIwODMwMV8wMTAiLCAiQjAxMDAyXzAwMSIpLCAKICAgICAgICAgIHllYXIgPSAyMDE4LCAKICAgICAgICAgIHN0YXRlID0gIk5KIiwgCiAgICAgICAgICBnZW9tZXRyeSA9IFRSVUUsIAogICAgICAgICAgb3V0cHV0ID0gIndpZGUiKSAlPiUKICByZW5hbWUoVG90YWxfUG9wID0gIEIwMTAwM18wMDFFLAogICAgICAgICBNZWRfSW5jID0gQjE5MDEzXzAwMUUsCiAgICAgICAgIE1lZF9BZ2UgPSBCMDEwMDJfMDAxRSwKICAgICAgICAgV2hpdGVfUG9wID0gQjAyMDAxXzAwMkUsCiAgICAgICAgIFRyYXZlbF9UaW1lID0gQjA4MDEzXzAwMUUsCiAgICAgICAgIE51bV9Db21tdXRlcnMgPSBCMDgwMTJfMDAxRSwKICAgICAgICAgTWVhbnNfb2ZfVHJhbnNwb3J0ID0gQjA4MzAxXzAwMUUsCiAgICAgICAgIFRvdGFsX1B1YmxpY19UcmFucyA9IEIwODMwMV8wMTBFKSAlPiUKICBzZWxlY3QoVG90YWxfUG9wLCBNZWRfSW5jLCBXaGl0ZV9Qb3AsIFRyYXZlbF9UaW1lLAogICAgICAgICBNZWFuc19vZl9UcmFuc3BvcnQsIFRvdGFsX1B1YmxpY19UcmFucywKICAgICAgICAgTWVkX0FnZSwKICAgICAgICAgR0VPSUQsIGdlb21ldHJ5KSAlPiUKICBtdXRhdGUoUGVyY2VudF9XaGl0ZSA9IFdoaXRlX1BvcCAvIFRvdGFsX1BvcCwKICAgICAgICAgTWVhbl9Db21tdXRlX1RpbWUgPSBUcmF2ZWxfVGltZSAvIFRvdGFsX1B1YmxpY19UcmFucywKICAgICAgICAgUGVyY2VudF9UYWtpbmdfUHVibGljX1RyYW5zID0gVG90YWxfUHVibGljX1RyYW5zIC8gTWVhbnNfb2ZfVHJhbnNwb3J0KQpOSlRyYWN0cyA8LSAKICBOSl9DZW5zdXMgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIGRpc3RpbmN0KEdFT0lELCAua2VlcF9hbGwgPSBUUlVFKSAlPiUKICBzZWxlY3QoR0VPSUQsIGdlb21ldHJ5KSAlPiUgCiAgc3Rfc2YKYGBgCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KZGF0X2NlbnN1cyA8LSBzdF9qb2luKG1lcmdlZF9kYXRhc2V0ICU+JSAKICAgICAgICAgIGZpbHRlcihpcy5uYShmcm9tX2xvbikgPT0gRkFMU0UgJgogICAgICAgICAgICAgICAgICAgaXMubmEoZnJvbV9sYXQpID09IEZBTFNFICYKICAgICAgICAgICAgICAgICAgIGlzLm5hKHRvX2xhdCkgPT0gRkFMU0UgJgogICAgICAgICAgICAgICAgICAgaXMubmEodG9fbG9uKSA9PSBGQUxTRSkgJT4lCiAgICAgICAgICBzdF9hc19zZiguLCBjb29yZHMgPSBjKCJmcm9tX2xvbiIsICJmcm9tX2xhdCIpLCBjcnMgPSA0MzI2KSwKICAgICAgICBOSlRyYWN0cyAlPiUKICAgICAgICAgIHN0X3RyYW5zZm9ybShjcnM9NDMyNiksCiAgICAgICAgam9pbj1zdF9pbnRlcnNlY3RzLAogICAgICAgICAgICAgIGxlZnQgPSBUUlVFKSAlPiUKICByZW5hbWUoRnJvbS5UcmFjdCA9IEdFT0lEKSAlPiUKICBtdXRhdGUoZnJvbV9sb24gPSB1bmxpc3QobWFwKGdlb21ldHJ5LCAxKSksCiAgICAgICAgIGZyb21fbGF0ID0gdW5saXN0KG1hcChnZW9tZXRyeSwgMikpKSU+JQogIGFzLmRhdGEuZnJhbWUoKSAlPiUKICBzZWxlY3QoLWdlb21ldHJ5KSAlPiUKICBzdF9hc19zZiguLCBjb29yZHMgPSBjKCJ0b19sb24iLCAidG9fbGF0IiksIGNycyA9IDQzMjYpICU+JQogIHN0X2pvaW4oLiwgTkpUcmFjdHMgJT4lCiAgICAgICAgICAgIHN0X3RyYW5zZm9ybShjcnM9NDMyNiksCiAgICAgICAgICBqb2luPXN0X2ludGVyc2VjdHMsCiAgICAgICAgICBsZWZ0ID0gVFJVRSkgJT4lCiAgcmVuYW1lKFRvLlRyYWN0ID0gR0VPSUQpICAlPiUKICBtdXRhdGUodG9fbG9uID0gdW5saXN0KG1hcChnZW9tZXRyeSwgMSkpLAogICAgICAgICB0b19sYXQgPSB1bmxpc3QobWFwKGdlb21ldHJ5LCAyKSkpJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHNlbGVjdCgtZ2VvbWV0cnkpCgpGcmlkYXkgPC0gCiAgbXV0YXRlKGRhdF9jZW5zdXMsCiAgICAgICAgIEZyaWRheSA9IGlmZWxzZShkb3R3ID09ICJGcmkiICYgaG91cihpbnRlcnZhbDYwKSA9PSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw2MCwgMCkpICU+JQogIGZpbHRlcihGcmlkYXkgIT0gMCkKCm1vbmRheSA8LSAKICBtdXRhdGUoZGF0X2NlbnN1cywKICAgICAgICAgbW9uZGF5ID0gaWZlbHNlKGRvdHcgPT0gIk1vbiIgJiBob3VyKGludGVydmFsNjApID09IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDYwLCAwKSkgJT4lCiAgZmlsdGVyKG1vbmRheSAhPSAwKQoKYGBgCgpUaGUgVGltZSBTZXJpZXMgUGxvdCBiZWxvdyBpbGx1c3RyYXRlIEJpa2Ugc2hhcmUgdHJpcGUgcGVyIGhvdXJzIGluIEplcnNleSBDaXR5LiBUaGUgc2t5Ymx1ZSBsaW5lIGlzIHVzZWQgdG8gdmlzdWFsaXplIHRoZSBGcmlkYXkuIEluIGNhbiBzZWUgdGhlIHJlbGF0aXZlbHkgaGlnaCBkZWxheSBvY2N1ciBpbiBtaWQtTWFyY2guCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZScJfQptZXJnZWRfZGF0YXNldCU+JQogIGRwbHlyOjpzZWxlY3QoaW50ZXJ2YWw2MCwgZnJvbSwgZGVsYXlfbWludXRlcykgJT4lCiAgZ2F0aGVyKFZhcmlhYmxlLCBWYWx1ZSwgLWludGVydmFsNjAsIC1mcm9tKSAlPiUKICAgIGdyb3VwX2J5KFZhcmlhYmxlLCBpbnRlcnZhbDYwKSAlPiUKICAgIHN1bW1hcml6ZShWYWx1ZSA9IG1lYW4oVmFsdWUpKSU+JQogICAgZ2dwbG90KGFlcyhpbnRlcnZhbDYwLCBWYWx1ZSkpICsgCiAgICAjZ2VvbV92bGluZShkYXRhID0gbW9uZGF5LCBhZXMoeGludGVyY2VwdCA9IG1vbmRheSksIGNvbG9yID0gInJlZCIpICsKICAgIGdlb21fdmxpbmUoZGF0YSA9IEZyaWRheSwgYWVzKHhpbnRlcmNlcHQgPSBGcmlkYXkpLCBjb2xvciA9ICJza3libHVlIikgKwogICAgZ2VvbV9saW5lKHNpemUgPSAwLjgsY29sb3VyPSJkYXJrYmx1ZSIpKwogICAgICBsYWJzKHRpdGxlID0gIkRlbGF5IGRpc3RyaWJ1dGlvbiBpbiBBIE1vbnRoIiwgc3VidGl0bGUgPSAiTkosIE1hcmNoLCAyMDE4IiwgIHggPSAiRGF5IiwgeT0gIk1lYW4gRGVsYXkiKSArCiAgICAgdGhlbWVfbWluaW1hbCgpCiAgcGxvdFRoZW1lCmBgYAoKIyMgRml4ZWQgZWZmZWN0cwoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmRlbGF5X3RpbWUgPC0gbWVyZ2VkX2RhdGFzZXQgJT4lCiAgZ3JvdXBfYnkodGltZV9vZl9kYXkpJT4lCiAgICBmaWx0ZXIoIWlzLm5hKHRpbWVfb2ZfZGF5KSkgJT4lCiAgc3VtbWFyaXplKG1lYW5fZGVsYXkgPSBtZWFuKGRlbGF5X21pbnV0ZXMpKQoKZGVsYXlfZGF5IDwtIG1lcmdlZF9kYXRhc2V0ICU+JQogIGdyb3VwX2J5KGRvdHcpJT4lCiAgICBmaWx0ZXIoIWlzLm5hKGRvdHcpKSAlPiUKICBzdW1tYXJpemUobWVhbl9kZWxheSA9IG1lYW4oZGVsYXlfbWludXRlcykpCgpkZWxheV93ZWVrIDwtIG1lcmdlZF9kYXRhc2V0ICU+JQogIGdyb3VwX2J5KHdlZWtlbmQpJT4lCiAgc3VtbWFyaXplKG1lYW5fZGVsYXkgPSBtZWFuKGRlbGF5X21pbnV0ZXMpKQoKZGVsYXlfaG91ciA8LSBtZXJnZWRfZGF0YXNldCAlPiUKICBncm91cF9ieShob3VyKGludGVydmFsNjApKSU+JQogIHN1bW1hcml6ZShtZWFuX2RlbGF5ID0gbWVhbihkZWxheV9taW51dGVzKSklPiUKICByZW5hbWUoaG91ciA9ICdob3VyKGludGVydmFsNjApJykKCmRlbGF5X3NlcXVlbmNlIDwtIG1lcmdlZF9kYXRhc2V0ICU+JQogIGdyb3VwX2J5KHN0b3Bfc2VxdWVuY2UpJT4lCiAgc3VtbWFyaXplKG1lYW5fZGVsYXkgPSBtZWFuKGRlbGF5X21pbnV0ZXMpKQoKZGVsYXlfdGltZV93ZWVrIDwtIG1lcmdlZF9kYXRhc2V0ICU+JQogIGdyb3VwX2J5KHRpbWVfb2ZfZGF5LHdlZWtlbmQpJT4lCiAgc3VtbWFyaXplKG1lYW5fZGVsYXkgPSBtZWFuKGRlbGF5X21pbnV0ZXMpKQoKZGVsYXlfd2Vla19ob3VyIDwtIG1lcmdlZF9kYXRhc2V0ICU+JQogIGdyb3VwX2J5KHdlZWtlbmQsaG91cihpbnRlcnZhbDYwKSklPiUKICBzdW1tYXJpemUobWVhbl9kZWxheSA9IG1lYW4oZGVsYXlfbWludXRlcykpJT4lCiAgcmVuYW1lKGhvdXIgPSAnaG91cihpbnRlcnZhbDYwKScpCgpkZWxheV93ZWVrX2RheSA8LSBtZXJnZWRfZGF0YXNldCAlPiUKICBncm91cF9ieShkb3R3LGhvdXIoaW50ZXJ2YWw2MCkpJT4lCiAgc3VtbWFyaXplKG1lYW5fZGVsYXkgPSBtZWFuKGRlbGF5X21pbnV0ZXMpKSU+JQogIHJlbmFtZShob3VyID0gJ2hvdXIoaW50ZXJ2YWw2MCknKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQpncmlkLmFycmFuZ2UoZ2dwbG90KGRhdGEgPSBkZWxheV9kYXksIGFlcyh4ID0gZG90dywgeSA9IG1lYW5fZGVsYXkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsZmlsbCA9ICJkYXJrYmx1ZSIpICsKICBsYWJzKHRpdGxlID0gIkRlbGF5IG1pbnV0ZXMgaW4gYSB3ZWVrIiwgeCA9ICJEYXkgb2YgVGhlIFdlZWsiLCB5ID0gIk1lYW4gRGVsYXkiKSArCiAgdGhlbWVfbWluaW1hbCgpLAogIAogIGdncGxvdChkYXRhID0gZGVsYXlfaG91ciwgYWVzKHggPSBob3VyLCB5ID0gbWVhbl9kZWxheSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IixmaWxsID0gImRhcmtibHVlIikgKwogIGxhYnModGl0bGUgPSAiRGVsYXkgbWludXRlcyBpbiAyNCBob3VycyIsIHggPSAiSG91ciBpbiBhIGRheSIsIHkgPSAiTWVhbiBEZWxheSIpICsKICB0aGVtZV9taW5pbWFsKCksCiAgCiAgZ2dwbG90KGRhdGEgPSBkZWxheV9zZXF1ZW5jZSwgYWVzKHggPSBzdG9wX3NlcXVlbmNlLCB5ID0gbWVhbl9kZWxheSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IixmaWxsID0gImRhcmtibHVlIikgKwogIGxhYnModGl0bGUgPSAiRGVsYXkgbWludXRlcyBpbiBlYWNoIHNlcXVlbmNlIiwgeCA9ICJTdG9wIFNlcXVlbmNlIiwgeSA9ICJNZWFuIERlbGF5IikgKwogIHRoZW1lX21pbmltYWwoKSwKICAKICBnZ3Bsb3QoZGF0YSA9IGRlbGF5X3RpbWUsIGFlcyh4ID0gdGltZV9vZl9kYXksIHkgPSBtZWFuX2RlbGF5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLGZpbGwgPSAiZGFya2JsdWUiKSArCiAgbGFicyh0aXRsZSA9ICJEZWxheSBtaW51dGVzIGluIGEgd2VlayIsIHggPSAiRGF5IG9mIFRoZSBXZWVrIiwgeSA9ICJNZWFuIERlbGF5IikgKwogIHRoZW1lX21pbmltYWwoKSwKICAKICBucm93PTIpCgpgYGAKClRoZSBmb2xsb3dpbmcgdGltZSBzZXJpZXMgcGxvdHMgZGlzcGxheSBkZWxheSBtaW51dGVzIGluIE5KIFRyYW5zaXQsIGJyb2tlbiBkb3duIGJ5IGRheSBvZiB0aGUgd2VlayBhbmQgYnkgd2Vla2RheXMgdmVyc3VzIHdlZWtlbmRzLiBUaGUgZGF0YSBzaG93cyBhIHBlYWsgaW4gZGVsYXkgbWlubnV0ZXMgb24gU3VuZGF5LCB3aXRoIG92ZXJhbGwgaGlnaGVyIGRlbGF5IG9uIHdlZWtlbmRzIGNvbXBhcmVkIHRvIHdlZWtkYXlzLiBUaGlzIHRyZW5kIGluZGljYXRlcyB0aGF0IGRlbGF5IHNpdHVhdGlvbiBpcyBtb3JlIGNvbW1vbmx5IGhhcHBlbiBpbiB3ZWVrZW5kLgoKYGBge3Isd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmRlbGF5X3dlZWtfaG91ciA8LSBtZXJnZWRfZGF0YXNldCAlPiUKICBncm91cF9ieSh3ZWVrZW5kLGhvdXIoaW50ZXJ2YWw2MCkpJT4lCiAgc3VtbWFyaXplKG1lYW5fZGVsYXkgPSBtZWFuKGRlbGF5X21pbnV0ZXMpKSU+JQogIHJlbmFtZShob3VyID0gJ2hvdXIoaW50ZXJ2YWw2MCknKQoKZ2dwbG90KGRhdGEgPSBkZWxheV93ZWVrX2hvdXIsIGFlcyh4ID0gaG91ciwgeSA9IG1lYW5fZGVsYXksIGNvbG9yID0gd2Vla2VuZCkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUyKSArCiAgbGFicyh0aXRsZSA9ICJUaGUgZGVsYXkgdW5kZXIgd2VlayBhbmQgdGltZSIsIHggPSAiSG91ciIsIHkgPSAiRGVsYXkgTWludXRlcyIpICsKICB0aGVtZV9taW5pbWFsKCkKICAKYGBgCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KcGFsZXR0ZSA8LSBjKAogICIjMWI5ZTc3IiwgIyBUZWFsIGdyZWVuCiAgIiNkOTVmMDIiLCAjIFZpYnJhbnQgb3JhbmdlCiAgIiM3NTcwYjMiLCAjIE11dGVkIHB1cnBsZQogICIjZTcyOThhIiwgIyBCcmlnaHQgcGluawogICIjNjZhNjFlIiwgIyBMZWFmIGdyZWVuCiAgIiNlNmFiMDIiLCAjIEdvbGRlbiB5ZWxsb3cKICAiI2E2NzYxZCIgICMgV2FybSBicm93bgopCgpkZWxheV93ZWVrX2RheSA8LSBtZXJnZWRfZGF0YXNldCAlPiUKICBncm91cF9ieShkb3R3LGhvdXIoaW50ZXJ2YWw2MCkpJT4lCiAgICAgIGZpbHRlcighaXMubmEoZG90dykpICU+JQogIHN1bW1hcml6ZShtZWFuX2RlbGF5ID0gbWVhbihkZWxheV9taW51dGVzKSklPiUKICByZW5hbWUoaG91ciA9ICdob3VyKGludGVydmFsNjApJykKCmdncGxvdChkYXRhID0gZGVsYXlfd2Vla19kYXksIGFlcyh4ID0gaG91ciwgeSA9IG1lYW5fZGVsYXksIGNvbG9yID0gZG90dykpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUpICsKICBsYWJzKHRpdGxlID0gIlRoZSBkZWxheSB1bmRlciB3ZWVrIGFuZCB0aW1lIiwgeCA9ICJIb3VyIiwgeSA9ICJEZWxheSBNaW51dGVzIikgKwogIHRoZW1lX21pbmltYWwoKQoKYGBgCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KbWVyZ2VkX2RhdGFzZXQgJT4lICAgICAgICAgICAgICAgIAogIGZpbHRlcighaXMubmEodGltZV9vZl9kYXkpKSAlPiUKICBncm91cF9ieShmcm9tLCB0aW1lX29mX2RheSklPiUKICBzdW1tYXJpemUobWVhbl9kZWxheSA9IG1lYW4oZGVsYXlfbWludXRlcykpJT4lCiAgZ2dwbG90KCkrCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKG1lYW5fZGVsYXkpLCBiaW53aWR0aCA9IDEpKwogIGxhYnModGl0bGU9Ik1lYW4gZGVsYXkgbWluLiBOSiBUcmFuc2l0LCBNYXJjaCwgMjAxOCIsCiAgICAgICB4PSJNZWFuIGRlbGF5IG1pbiIsIAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgZmFjZXRfd3JhcCh+dGltZV9vZl9kYXkpKwogIHBsb3RUaGVtZQpgYGAKClRoZSBtYXBzIGJlbG93IGlsbHVzdHJhdGUgdGhlIGhvdXJseSBkZWxheXMgYnkgc3RhdGlvbi4gV2Vla2VuZHMgdGVuZCB0byBleHBlcmllbmNlIHJlbGF0aXZlbHkgaGlnaGVyIGRlbGF5cyBjb21wYXJlZCB0byB3ZWVrZGF5cy4gT3ZlcmFsbCwgZGVsYXllZCBzdGF0aW9ucyBhcHBlYXIgdG8gYmUgc3BhdGlhbGx5IGRpc3RyaWJ1dGVkIGluIGEgcmFuZG9tIHBhdHRlcm4sIHdpdGhvdXQgYSBjbGVhciBjbHVzdGVyaW5nIG9yIHNwZWNpZmljIGdlb2dyYXBoaWMgY29uY2VudHJhdGlvbi4KCmBgYHtyfQoKZ2dwbG90KCkgKwogICMgUGxvdCBOSlRyYWN0cyBhcyBhIGJhc2UgbWFwCiAgZ2VvbV9zZihkYXRhID0gTkpUcmFjdHMgJT4lIAogICAgICAgICAgICBzdF90cmFuc2Zvcm0oY3JzID0gNDMyNiksIGNvbG9yID0gIndoaXRlIikgKwogIAogICMgQWRkIHBvaW50cyBmb3IgYmlrZSBzaGFyZSB0cmlwcwogIGdlb21fcG9pbnQoZGF0YSA9IG1lcmdlZF9kYXRhc2V0ICU+JSAKICAgICAgICAgICAgICAgbXV0YXRlKHdlZWtlbmQgPSBpZmVsc2UoZG90dyAlaW4lIGMoIlN1biIsICJTYXQiKSwgIldlZWtlbmQiLCAiV2Vla2RheSIpLAogICAgICAgICAgICAgICAgICAgICAgdGltZV9vZl9kYXkgPSBjYXNlX3doZW4oCiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIoaW50ZXJ2YWw2MCkgPCA3IHwgaG91cihpbnRlcnZhbDYwKSA+IDE5IH4gIk92ZXJuaWdodCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIoaW50ZXJ2YWw2MCkgPj0gNyAmIGhvdXIoaW50ZXJ2YWw2MCkgPCAxMCB+ICJBTSBSdXNoIiwKICAgICAgICAgICAgICAgICAgICAgICAgaG91cihpbnRlcnZhbDYwKSA+PSAxMCAmIGhvdXIoaW50ZXJ2YWw2MCkgPCAxNSB+ICJNaWQtRGF5IiwKICAgICAgICAgICAgICAgICAgICAgICAgaG91cihpbnRlcnZhbDYwKSA+PSAxNSAmIGhvdXIoaW50ZXJ2YWw2MCkgPD0gMTkgfiAiUE0gUnVzaCIKICAgICAgICAgICAgICAgICAgICAgICkpICU+JQogICAgICAgICAgICAgICBmaWx0ZXIoIWlzLm5hKHRpbWVfb2ZfZGF5KSkgJT4lCiAgICAgICAgICAgICAgIGdyb3VwX2J5KGZyb21faWQsIGZyb21fbGF0LCBmcm9tX2xvbiwgd2Vla2VuZCwgdGltZV9vZl9kYXkpICU+JQogICAgICAgICAgICAgICBzdW1tYXJpemUobWVhbl9kZWxheSA9IG1lYW4oZGVsYXlfbWludXRlcywgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgICAgICAgICAgICAgIHVuZ3JvdXAoKSwKICAgICAgICAgICAgIGFlcyh4ID0gZnJvbV9sb24sIHkgPSBmcm9tX2xhdCwgY29sb3IgPSBtZWFuX2RlbGF5KSwgCiAgICAgICAgCiAgICAgICAgICAgICBhbHBoYSA9IDAuOSwgc2l6ZSA9IDAuOSkgKwogIAogICMgQWRkIGNvbG9yIHNjYWxlIGZvciBtZWFuIGRlbGF5CiAgc2NhbGVfY29sb3VyX3ZpcmlkaXMoZGlyZWN0aW9uID0gLTEsIGRpc2NyZXRlID0gRkFMU0UsIG9wdGlvbiA9ICJFIikgKwogIAogICMgU2V0IGF4aXMgbGltaXRzCiAgeWxpbShtaW4obWVyZ2VkX2RhdGFzZXQkZnJvbV9sYXQpLCBtYXgobWVyZ2VkX2RhdGFzZXQkZnJvbV9sYXQpKSArCiAgeGxpbShtaW4obWVyZ2VkX2RhdGFzZXQkZnJvbV9sb24pLCBtYXgobWVyZ2VkX2RhdGFzZXQkZnJvbV9sb24pKSArCiAgCiAgIyBBZGQgZmFjZXRzIGZvciB3ZWVrZW5kIGFuZCB0aW1lIG9mIGRheQogIGZhY2V0X2dyaWQod2Vla2VuZCB+IHRpbWVfb2ZfZGF5KSArCiAgCiAgIyBBZGQgbGFiZWxzIGFuZCB0aGVtZXMKICBsYWJzKHRpdGxlID0gImRlbGF5IG1pbiBieSBzdGF0aW9uLiBOSiwgbWFyY2gsIDIwMTgiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICAgIyBSZW1vdmUgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSBmcm9tIGF4ZXMKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICB0aGVtZV92b2lkKCkKCmBgYAoKVGhlIHBsb3QgYmVsb3cgZGlzcGxheXMgYW4gYW5pbWF0ZWQgbWFwIG9mIHN0YXRpb24gZGVsYXlzLCByZXZlYWxpbmcgYSByZWxhdGl2ZWx5IGhpZ2ggZnJlcXVlbmN5IG9mIGRlbGF5cyBpbiB0aGUgbm9ydGhlcm4gYXJlYSBuZWFyIE1hbmhhdHRhbiwgTlkuIFRoaXMgc3VnZ2VzdHMgdGhhdCBzdGF0aW9ucyBjbG9zZXIgdG8gTWFuaGF0dGFuIGV4cGVyaWVuY2UgbW9yZSBmcmVxdWVudCBkZWxheXMsIHBvdGVudGlhbGx5IGR1ZSB0byBoaWdoZXIgdHJhZmZpYywgY29uZ2VzdGlvbiwgb3Igb3BlcmF0aW9uYWwgY29tcGxleGl0eSBpbiB0aGlzIHJlZ2lvbi4KCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZWxheV9zdG9wX3RpbWUgPC0gbWVyZ2VkX2RhdGFzZXQgJT4lCiAgZ3JvdXBfYnkoZnJvbSx0byxob3VyKGludGVydmFsNjApKSU+JQogIHN1bW1hcml6ZShtZWFuX2RlbGF5ID0gbWVhbihkZWxheV9taW51dGVzKSklPiUKICByZW5hbWUoaG91ciA9ICdob3VyKGludGVydmFsNjApJyklPiUKICBsZWZ0X2pvaW4oc3RvcCxieT1jKCdmcm9tJz0nU1RBVElPTl9JRCcpKSU+JQogIHN0X2FzX3NmKGNvb3JkcyA9IGMoIkxPTkdJVFVERSIsICJMQVRJVFVERSIpLCBjcnMgPSA0MzI2KQoKZ2dwbG90KCkgKwogICAgZ2VvbV9zZihkYXRhID0gTkpUcmFjdHMsIGNvbG9yID0gJ3doaXRlJykgKyAKICAgIGdlb21fc2YoZGF0YSA9IGRlbGF5X3N0b3BfdGltZSwgYWVzKHNpemUgPSBtZWFuX2RlbGF5LGNvbG9yID0gbWVhbl9kZWxheSksIAogICAgICAgICAgICBmaWxsID0gInRyYW5zcGFyZW50IiwgYWxwaGEgPSAwLjgpICsKICAKICAgIHNjYWxlX2NvbG91cl92aXJpZGlzKAogICAgICAgICAgbmFtZSA9ICJNZWFuIGRlbGF5IiwgIyBDb21iaW5lZCB0aXRsZSBmb3IgY29sb3IgYW5kIHNpemUKICAgIGRpcmVjdGlvbiA9IC0xLAogICAgb3B0aW9uID0gIkUiLAogICAgZGlzY3JldGUgPSBGQUxTRQogICkgKwogIHNjYWxlX3NpemVfY29udGludW91cygKICAgIG5hbWUgPSAiTWVhbiBkZWxheSIsICMgU2FtZSB0aXRsZSBhcyBjb2xvciB0byBjb21iaW5lIGxlZ2VuZAogICAgcmFuZ2UgPSBjKDEsIDUpICMgQWRqdXN0IHNpemUgcmFuZ2UgYXMgbmVlZGVkCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoKSAjIFVzZSBhIHNpbmdsZSBsZWdlbmQgZ3VpZGUKICApICsKCiAgICAjc2NhbGVfY29sb3VyX3ZpcmlkaXMoZGlyZWN0aW9uID0gLTEsZGlzY3JldGUgPSBGQUxTRSwgb3B0aW9uID0gIkQiKSArCiAgICBsYWJzKHRpdGxlID0gIlN0YXRpb24gRGVsYXkgRm9yIE9uZSBEYXkgaW4gTWFyY2gsIDIwMTgiLAogICAgICAgICBzdWJ0aXRsZSA9ICJIb3VycyBpbiBhIGRheToge2N1cnJlbnRfZnJhbWV9IikgKwogICAgdHJhbnNpdGlvbl9tYW51YWwoaG91cikrIG1hcFRoZW1lK3RoZW1lX21pbmltYWwoKSsgIHRoZW1lX3ZvaWQoKQoKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Kc3R1ZHkucGFuZWwgPC0gCiAgZXhwYW5kLmdyaWQoaW50ZXJ2YWw2MD11bmlxdWUoZGF0X2NlbnN1cyRpbnRlcnZhbDYwKSwgCiAgICAgICAgICAgICAgZnJvbV9pZCA9IHVuaXF1ZShkYXRfY2Vuc3VzJGZyb21faWQpKSAlPiUKICBsZWZ0X2pvaW4oLiwgZGF0X2NlbnN1cyAlPiUKICAgICAgICAgICAgICBzZWxlY3QoZnJvbV9pZCwgZnJvbSwgRnJvbS5UcmFjdCwgZnJvbV9sYXQsIGZyb21fbG9uICklPiUKICAgICAgICAgICAgICBkaXN0aW5jdCgpICU+JQogICAgICAgICAgICAgIGdyb3VwX2J5KGZyb21faWQpICU+JQogICAgICAgICAgICAgIHNsaWNlKDEpKQoKbnJvdyhzdHVkeS5wYW5lbCkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KcmlkZS5wYW5lbF8xIDwtIAogIGRhdF9jZW5zdXMgJT4lCiAgcmlnaHRfam9pbihzdHVkeS5wYW5lbCkgJT4lIAogIGdyb3VwX2J5KHNjaGVkdWxlZF90aW1lLCBpbnRlcnZhbDYwLCBmcm9tX2lkLCBmcm9tLCBGcm9tLlRyYWN0LCBmcm9tX2xhdCwgZnJvbV9sb24sIGRlbGF5X21pbnV0ZXMsc3RvcF9zZXF1ZW5jZSx0cmFpbl9pZCwgdG8sIHdlZWtlbmQsIGRvdHcpICU+JQogIHN1bW1hcml6ZShtZWFuX2RlbGF5ID0gbWVhbihkZWxheV9taW51dGVzLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBsZWZ0X2pvaW4od2VhdGhlci5QYW5lbCkgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihpcy5uYShmcm9tX2lkKSA9PSBGQUxTRSkgJT4lCiAgbXV0YXRlKHdlZWsgPSB3ZWVrKGludGVydmFsNjApLAogICAgICAgICBkb3R3ID0gd2RheShpbnRlcnZhbDYwLCBsYWJlbCA9IFRSVUUpKSAlPiUKICBmaWx0ZXIoaXMubmEoRnJvbS5UcmFjdCkgPT0gRkFMU0UpICU+JSAKICBtdXRhdGUoaW50ZXJ2YWwxNSA9IGZsb29yX2RhdGUoeW1kX2htcyhzY2hlZHVsZWRfdGltZSksIHVuaXQgPSAiMTUgbWlucyIpKQoKYGBgCgojIyBUZW1wb3JhbCAmIFNwYXRpYWwgbGFnCgpDcmVhdGluZyBTcGF0aWFsIGFuZCB0aW1lIGxhZyB2YXJpYWJsZXMgY2FwdHVyZSB0aGUgZGVwZW5kZW5jZSBvZiBwaGVub21lbmEgb24gZ2Vvc3BhdGlhbCBhbmQgdGltZSBzZXJpZXMsIHRoZXJlYnkgaW1wcm92aW5nIHRoZSBwcmVkaWN0aXZlIGFjY3VyYWN5IGFuZCBleHBsYW5hdG9yeSBwb3dlciBvZiB0aGUgbW9kZWwuIEluIHByYWN0aWNhbCBhcHBsaWNhdGlvbnMsIHRoZXNlIHZhcmlhYmxlcyBjYW4gaGVscCB1cyBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgZHluYW1pYyBuYXR1cmUgb2YgZGVsYXkgYW5kIGV4dGVybmFsIGluZmx1ZW5jZXMuCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KcmlkZS5wYW5lbCA8LSAKICBsZWZ0X2pvaW4ocmlkZS5wYW5lbF8xLCBOSl9DZW5zdXMgJT4lCiAgICAgICAgICAgICAgYXMuZGF0YS5mcmFtZSgpICU+JQogICAgICAgICAgICAgIHNlbGVjdCgtZ2VvbWV0cnkpLCBieSA9IGMoIkZyb20uVHJhY3QiID0gIkdFT0lEIikpCgoKcmlkZS5wYW5lbF9taW4gPC0gCiAgcmlkZS5wYW5lbCAlPiUgCiAgYXJyYW5nZShmcm9tX2lkLCBpbnRlcnZhbDE1KSAlPiUgCm11dGF0ZShsYWcxNW1pbiA9IGRwbHlyOjpsYWcoZGVsYXlfbWludXRlcywxKSwKICAgICAgICAgbGFnMzBtaW4gPSBkcGx5cjo6bGFnKGRlbGF5X21pbnV0ZXMsMiksCiAgICAgICAgIGxhZzQ1bWluID0gZHBseXI6OmxhZyhkZWxheV9taW51dGVzLDMpLAogICAgICAgICBsYWcxaCA9IGRwbHlyOjpsYWcoZGVsYXlfbWludXRlcyw0KSwKICAgICAgICAgbGFnMWgxNW1pbiA9IGRwbHlyOjpsYWcoZGVsYXlfbWludXRlcyw1KSwKICAgICAgICAgbGFnMWgzMG1pbiA9IGRwbHlyOjpsYWcoZGVsYXlfbWludXRlcyw2KSwKICAgICAgICAgbGFnMWg0NW1pbiA9IGRwbHlyOjpsYWcoZGVsYXlfbWludXRlcyw3KSwKICAgICAgICAgbGFnMmggPSBkcGx5cjo6bGFnKGRlbGF5X21pbnV0ZXMsOCksCiAgICAgICAgIGxhZzJoMTVtaW4gPSBkcGx5cjo6bGFnKGRlbGF5X21pbnV0ZXMsOSksCiAgICAgICAgIGxhZzJoMzBtaW4gPSBkcGx5cjo6bGFnKGRlbGF5X21pbnV0ZXMsMTApLAogICAgICAgICBsYWcyaDQ1bWluID0gZHBseXI6OmxhZyhkZWxheV9taW51dGVzLDExKSwKICAgICAgICAgbGFnM2ggPSBkcGx5cjo6bGFnKGRlbGF5X21pbnV0ZXMsMTIpLAogICAgICAgICAjbGFnMWRheSA9IGRwbHlyOjpsYWcoZGVsYXlfbWludXRlcyw5NikKICAgICAgICkgJT4lIAogICBtdXRhdGUobWluXzE1ID0geWRheShpbnRlcnZhbDE1KSkgIAoKYXMuZGF0YS5mcmFtZShyaWRlLnBhbmVsX21pbikgJT4lCiAgICBncm91cF9ieShpbnRlcnZhbDE1KSAlPiUgCiAgICBzdW1tYXJpc2VfYXQodmFycyhzdGFydHNfd2l0aCgibGFnIiksICJkZWxheV9taW51dGVzIiksIG1lYW4sIG5hLnJtID0gVFJVRSkgJT4lCiAgICBnYXRoZXIoVmFyaWFibGUsIFZhbHVlLCAtaW50ZXJ2YWwxNSwgLWRlbGF5X21pbnV0ZXMpICU+JQogICAgbXV0YXRlKFZhcmlhYmxlID0gZmFjdG9yKFZhcmlhYmxlLCBsZXZlbHM9YygibGFnMTVtaW4iLCJsYWczMG1pbiIsImxhZzQ1bWluIiwibGFnMWgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGFnMWgxNW1pbiIsImxhZzFoMzBtaW4iLCJsYWcxaDQ1bWluIiwibGFnMmgiLCJsYWcyaDE1bWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhZzJoMzBtaW4iLCJsYWcyaDQ1bWluIiwibGFnM2giKSkpJT4lCiAgICBncm91cF9ieShWYXJpYWJsZSkgJT4lICAKICAgIHN1bW1hcml6ZShjb3JyZWxhdGlvbiA9IHJvdW5kKGNvcihWYWx1ZSwgZGVsYXlfbWludXRlcywgdXNlPSJjb21wbGV0ZS5vYnMiKSwyKSkKCgpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQpyaWRlLnBhbmVsX3N0YXRpb24gPC0gCiAgcmlkZS5wYW5lbF9taW4gJT4lIAogIGFycmFuZ2UodHJhaW5faWQsIGludGVydmFsMTUsIHN0b3Bfc2VxdWVuY2UpICU+JSAKICBtdXRhdGUoCiAgICBsYWdzc3RhdGlvbiA9IGlmX2Vsc2Uoc3RvcF9zZXF1ZW5jZSA9PSAxLCAwLCBsYWcoZGVsYXlfbWludXRlcywgMSkpLAogICAgbGFnczJzdGF0aW9uID0gaWZfZWxzZShzdG9wX3NlcXVlbmNlIDw9IDIsIDAsIGxhZyhkZWxheV9taW51dGVzLCAyKSksCiAgICBsYWdzM3N0YXRpb24gPSBpZl9lbHNlKHN0b3Bfc2VxdWVuY2UgPD0gMywgMCwgbGFnKGRlbGF5X21pbnV0ZXMsIDMpKSwKICAgIGxhZ3M0c3RhdGlvbiA9IGlmX2Vsc2Uoc3RvcF9zZXF1ZW5jZSA8PSA0LCAwLCBsYWcoZGVsYXlfbWludXRlcywgNCkpLAogICAgbGFnczVzdGF0aW9uID0gaWZfZWxzZShzdG9wX3NlcXVlbmNlIDw9IDUsIDAsIGxhZyhkZWxheV9taW51dGVzLCA1KSksCiAgICBsYWdzNnN0YXRpb24gPSBpZl9lbHNlKHN0b3Bfc2VxdWVuY2UgPD0gNiwgMCwgbGFnKGRlbGF5X21pbnV0ZXMsIDYpKSwKICAgIGxhZ3M3c3RhdGlvbiA9IGlmX2Vsc2Uoc3RvcF9zZXF1ZW5jZSA8PSA3LCAwLCBsYWcoZGVsYXlfbWludXRlcywgNykpLAogICAgbGFnczhzdGF0aW9uID0gaWZfZWxzZShzdG9wX3NlcXVlbmNlIDw9IDgsIDAsIGxhZyhkZWxheV9taW51dGVzLCA4KSkKICApCgphcy5kYXRhLmZyYW1lKHJpZGUucGFuZWxfc3RhdGlvbikgJT4lCiAgZ3JvdXBfYnkodHJhaW5faWQpICU+JSAKICBzdW1tYXJpc2VfYXQodmFycyhzdGFydHNfd2l0aCgibGFncyIpLCAiZGVsYXlfbWludXRlcyIpLCBtZWFuLCBuYS5ybSA9IFRSVUUpICU+JQogIGdhdGhlcihWYXJpYWJsZSwgVmFsdWUsIC10cmFpbl9pZCwgLWRlbGF5X21pbnV0ZXMpICU+JSAjIFJlbW92ZSBgaW50ZXJ2YWwxNWAgaWYgdW5uZWNlc3NhcnkKICBtdXRhdGUoVmFyaWFibGUgPSBmYWN0b3IoVmFyaWFibGUsIGxldmVscyA9IGMoCiAgICAibGFnc3N0YXRpb24iLCAibGFnczJzdGF0aW9uIiwgImxhZ3Mzc3RhdGlvbiIsICJsYWdzNHN0YXRpb24iLAogICAgImxhZ3M1c3RhdGlvbiIsICJsYWdzNnN0YXRpb24iLCAibGFnczdzdGF0aW9uIiwgImxhZ3M4c3RhdGlvbiIKICApKSkgJT4lCiAgZ3JvdXBfYnkoVmFyaWFibGUpICU+JSAgCiAgc3VtbWFyaXplKGNvcnJlbGF0aW9uID0gcm91bmQoY29yKFZhbHVlLCBkZWxheV9taW51dGVzLCB1c2UgPSAiY29tcGxldGUub2JzIiksIDIpKQoKYGBgCgpUaGUgdGltZSBsYWcgdmFyaWFibGVzIGNvbnNpZGVycyBob3cgYSBwaGVub21lbm9uIGF0IG9uZSBwb2ludCBpbiB0aW1lIGlzIGFmZmVjdGVkIGJ5IGEgcHJldmlvdXMgcG9pbnQgaW4gdGltZS4KClRoZSBmb2xsb3dpbmcgc2NhdHRlcnBsb3RzIHByZXNlbnQgdGhhdCBUZW1wb3JhbCBsYWcgaGFzIGNvcnJlbGF0aW9uIHdpdGggdGhlIGRlbGF5LgoKU2hvcnQgdGltZSBsYWdzIChzdWNoIGFzIGxhZzE1bWluIGFuZCBsYWczMG1pbikgaGF2ZSBhIGdyZWF0ZXIgaW1wYWN0IG9uIGN1cnJlbnQgZGVsYXlzIGFuZCBzaG91bGQgYmUgcHJpb3JpdGl6ZWQgYXMgZmVhdHVyZXMgaW4gdGhlIG1vZGVsLiBIb3dldmVyLCBMb25nLXRlcm0gbGFncyAoZS5nLiwgbGFnMmggYW5kIGxhZzNoKSBhcmUgbGVzcyByZWxldmFudCBidXQgc3RpbGwgY2FwdHVyZSBsb25nLXRlcm0gZGVsYXkgdHJlbmRzLgoKYGBge3IgZmlnLndpZHRoPTE1LCBmaWcuaGVpZ2h0PTUsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojIFByZXBhcmUgdGhlIGRhdGEKc2NhdHRlcl9kYXRhIDwtIGFzLmRhdGEuZnJhbWUocmlkZS5wYW5lbF9taW4pICU+JQogIGdyb3VwX2J5KGludGVydmFsMTUpICU+JSAKICBzdW1tYXJpc2VfYXQodmFycyhzdGFydHNfd2l0aCgibGFnIiksICJkZWxheV9taW51dGVzIiksIG1lYW4sIG5hLnJtID0gVFJVRSkgJT4lCiAgZ2F0aGVyKFZhcmlhYmxlLCBWYWx1ZSwgLWludGVydmFsMTUsIC1kZWxheV9taW51dGVzKSAlPiUKICBtdXRhdGUoVmFyaWFibGUgPSBmYWN0b3IoVmFyaWFibGUsIGxldmVscyA9IGMoImxhZzE1bWluIiwgImxhZzMwbWluIiwgImxhZzQ1bWluIiwgImxhZzFoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhZzFoMTVtaW4iLCAibGFnMWgzMG1pbiIsICJsYWcxaDQ1bWluIiwgImxhZzJoIiwgImxhZzJoMTVtaW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGFnMmgzMG1pbiIsICJsYWcyaDQ1bWluIiwgImxhZzNoIikgKSkgJT4lIAogICAgZmlsdGVyKCFpcy5uYShWYXJpYWJsZSkpCgoKIyBDb21wdXRlIGNvcnJlbGF0aW9uIHZhbHVlcwpjb3JyZWxhdGlvbnMgPC0gc2NhdHRlcl9kYXRhICU+JQogIGdyb3VwX2J5KFZhcmlhYmxlKSAlPiUKICBzdW1tYXJpemUoY29ycmVsYXRpb24gPSByb3VuZChjb3IoVmFsdWUsIGRlbGF5X21pbnV0ZXMsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKSwgMikpICU+JSAKICBmaWx0ZXIoIWlzLm5hKFZhcmlhYmxlKSkKCiMgQ3JlYXRlIHNjYXR0ZXJwbG90CmdncGxvdChzY2F0dGVyX2RhdGEsIGFlcyh4ID0gVmFsdWUsIHkgPSBkZWxheV9taW51dGVzKSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAiZ3JleTIwIiwgYWxwaGEgPSAwLjYsIHNpemUgPSAxKSArICMgVW5pZm9ybSBjb2xvciBmb3IgcG9pbnRzCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAicmVkIiwgc2UgPSBGQUxTRSwgc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKyAjIEJlc3QtZml0IGxpbmUKICBmYWNldF93cmFwKH5WYXJpYWJsZSwgc2NhbGVzID0gImZyZWUiLCBucm93PTIpICsgIyBTZXBhcmF0ZSBzY2F0dGVycGxvdHMgZm9yIGVhY2ggVmFyaWFibGUKICBsYWJzKAogICAgdGl0bGUgPSAiU2NhdHRlcnBsb3Qgb2YgTGFnIFZhcmlhYmxlcyB2cyBEZWxheSBNaW51dGVzIiwKICAgIHggPSAiTGFnIFZhbHVlIiwKICAgIHkgPSAiRGVsYXkgTWludXRlcyIKICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogICMgQWRkIGNvcnJlbGF0aW9uIHZhbHVlcyBhcyBhbm5vdGF0aW9ucwogIGdlb21fdGV4dCgKICAgIGRhdGEgPSBjb3JyZWxhdGlvbnMsCiAgICBhZXMobGFiZWwgPSBwYXN0ZSgiciA9IiwgY29ycmVsYXRpb24pLCB4ID0gSW5mLCB5ID0gSW5mKSwKICAgIGhqdXN0ID0gMS4xLCB2anVzdCA9IDEuMiwgaW5oZXJpdC5hZXMgPSBGQUxTRQogICkKCgpgYGAKClNwYXRpYWwgbGFnIHZhcmlhYmxlcyBjb25zaWRlciBob3cgcGhlbm9tZW5hIGluIG9uZSBsb2NhdGlvbiBhcmUgYWZmZWN0ZWQgYnkgbmVpZ2hib3JpbmcgbG9jYXRpb25zLCBlc3BlY2lhbGx5IGluIGdlb2dyYXBoaWMgc3BhY2UuIFRoZSBmb2xsb3dpbmcgc2NhdHRlcnBsb3RzIGluZGljYXRlIHRoYXQgc3BhdGlhbCBsYWcgYXJlIHZlcnkgc3Ryb25nIGNvcnJlbGF0aW9uIHdpdGggdGhlIGRlbGF5LiBIb3dldmVyLCB0aGUgY29ycmVsYXRpb24gYXJlIGRlY3JlYXNpbmcgd2l0aCBlYWNoIGFkZGl0aW9uYWwgbGFnIHN0YXRpb25zLCBidXQgdGhlIHByZWRpY3RpdmUgcG93ZXIgYXJlIHN0cm9uZ2VyIGluIG92ZXJhbGwuCgpgYGB7ciBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9NSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCiMgUHJlcGFyZSB0aGUgZGF0YQpzY2F0dGVyX2RhdGFfc3RhdGlvbiA8LSBhcy5kYXRhLmZyYW1lKHJpZGUucGFuZWxfc3RhdGlvbikgJT4lCiAgZ3JvdXBfYnkodHJhaW5faWQpICU+JSAKICBzdW1tYXJpc2VfYXQodmFycyhzdGFydHNfd2l0aCgibGFncyIpLCAiZGVsYXlfbWludXRlcyIpLCBtZWFuLCBuYS5ybSA9IFRSVUUpICU+JQogIGdhdGhlcihWYXJpYWJsZSwgVmFsdWUsIC10cmFpbl9pZCwgLWRlbGF5X21pbnV0ZXMpICU+JQogIG11dGF0ZShWYXJpYWJsZSA9IGZhY3RvcihWYXJpYWJsZSwgbGV2ZWxzID0gYygKICAgICJsYWdzc3RhdGlvbiIsICJsYWdzMnN0YXRpb24iLCAibGFnczNzdGF0aW9uIiwgImxhZ3M0c3RhdGlvbiIsCiAgICAibGFnczVzdGF0aW9uIiwgImxhZ3M2c3RhdGlvbiIsICJsYWdzN3N0YXRpb24iLCAibGFnczhzdGF0aW9uIgogICkpKQoKIyBDb21wdXRlIGNvcnJlbGF0aW9uIHZhbHVlcwpjb3JyZWxhdGlvbnNfc3RhdGlvbiA8LSBzY2F0dGVyX2RhdGFfc3RhdGlvbiAlPiUKICBncm91cF9ieShWYXJpYWJsZSkgJT4lCiAgc3VtbWFyaXplKGNvcnJlbGF0aW9uID0gcm91bmQoY29yKFZhbHVlLCBkZWxheV9taW51dGVzLCB1c2UgPSAiY29tcGxldGUub2JzIiksIDIpKQoKIyBDcmVhdGUgc2NhdHRlcnBsb3QKZ2dwbG90KHNjYXR0ZXJfZGF0YV9zdGF0aW9uLCBhZXMoeCA9IFZhbHVlLCB5ID0gZGVsYXlfbWludXRlcykpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImdyZXkyMCIsIGFscGhhID0gMC42LCBzaXplID0gMikgKyAjIFVuaWZvcm0gY29sb3IgZm9yIHBvaW50cwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gInJlZCIsIHNlID0gRkFMU0UsIHNpemUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArICMgQmVzdC1maXQgbGluZQogIGZhY2V0X3dyYXAoflZhcmlhYmxlLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3c9MSkgKyAjIFNlcGFyYXRlIHNjYXR0ZXJwbG90cyBmb3IgZWFjaCBWYXJpYWJsZQogIGxhYnMoCiAgICB0aXRsZSA9ICJTY2F0dGVycGxvdCBvZiBTdGF0aW9uIExhZ3MgdnMgRGVsYXkgTWludXRlcyIsCiAgICB4ID0gIkxhZyBWYWx1ZSIsCiAgICB5ID0gIkRlbGF5IE1pbnV0ZXMiCiAgKSArCiAgeGxpbSgwLDI1KSsKeWxpbSgwLDI1KSsKICB0aGVtZV9taW5pbWFsKCkgKwogICMgQWRkIGNvcnJlbGF0aW9uIHZhbHVlcyBhcyBhbm5vdGF0aW9ucwogIGdlb21fdGV4dCgKICAgIGRhdGEgPSBjb3JyZWxhdGlvbnNfc3RhdGlvbiwKICAgIGFlcyhsYWJlbCA9IHBhc3RlKCJyID0iLCBjb3JyZWxhdGlvbiksIHggPSBJbmYsIHkgPSBJbmYpLAogICAgaGp1c3QgPSAxLjEsIHZqdXN0ID0gMS4yLCBpbmhlcml0LmFlcyA9IEZBTFNFCiAgKQoKYGBgCgojIE1vZGVsCgpUaGlzIHNlY3Rpb24gc3BsaXQgZGF0YSBpbnRvIGEgdHJhaW5pbmcgYW5kIHRlc3Qgc2V0IGFuZCBkZXZlbG9wIGEgMyB3ZWVrIHRyYWluaW5nIHNldCBhbmQgYSAyIHdlZWsgdGVzdCBzZXQgb2YgYWxsIHRoZSBzdGF0aW9ucy4gSW4gdGhlIGZvbGxvd2luZyBhbmFseXNpcywgVGhyZWUgZGlmZmVyZW50IGxpbmVhciByZWdyZXNzaW9uIGFyZSBlc3RpbWF0ZWQgb24gYGRlbGF5LlRyYWluYC4KClNpbmNlIGRlbGF5cyBleGhpYml0IHNwYXRpYWwgYW5kIHRlbXBvcmFsIGNvcnJlbGF0aW9ucywgaW5jb3Jwb3JhdGluZyB0aW1lIGFuZCBzcGFjZSBmZWF0dXJlcyBpbnRvIHRoZSBtb2RlbHMgY2FuIGxlYWQgdG8gaW1wcm92ZWQgcHJlZGljdGlvbnMuIEFkZGl0aW9uYWxseSwgdmFyaWFibGVzIHN1Y2ggYXMgdGhlIG9yaWdpbiBhbmQgZGVzdGluYXRpb24gc3RhdGlvbnMgKGZyb20gYW5kIHRvKSwgd2hldGhlciBpdCBpcyBhIHdlZWtkYXkgb3Igd2Vla2VuZCwgdGVtcGVyYXR1cmUsIHByZWNpcGl0YXRpb24sIGFuZCBzdG9wIHNlcXVlbmNlIGFyZSBhbHNvIGluY2x1ZGVkIHRvIGZ1cnRoZXIgZW5oYW5jZSB0aGUgbW9kZWwncyBhY2N1cmFjeS4KCjEuICByZWcuMzAgKFByZWRpY3QgZGVsYXlzIHdpdGhpbiAzMCBtaW51dGVzKQoKLSAgIFNob3J0ZXIgbGFnIHZhcmlhYmxlcyBhcmUgdXNlZCwgc3VjaCBhcyBsYWc0NW1pbiwgbGFnMWgsIGxhZzFoMTVtaW4sIGV0Yy4gVGhlc2UgbGFnIHZhcmlhYmxlcyBjb3JyZXNwb25kIHRvIHRoZSBwb3NzaWJsZSBlZmZlY3RzIGluIHRoZSB0YXJnZXQgdGltZSByYW5nZS4KCi0gICBBdCB0aGUgc2FtZSB0aW1lLCBsYWdzM3N0YXRpb24sIGxhZ3M0c3RhdGlvbiwgbGFnczVzdGF0aW9uLCBhbmQgbGFnczZzdGF0aW9uIGNvbnRhaW4gbGFnZ2luZyBzaXRlIHZhcmlhYmxlcywgaW5kaWNhdGluZyB0aGUgcHJvcGFnYXRpb24gb2YgZGVsYXkgaW4gc3BhY2UuCgotICAgSXQgaXMgc3VpdGFibGUgZm9yIGFuYWx5emluZyB0aGUgcHJlZGljdGlvbiBvZiBkZWxheXMgaW4gYSBzaG9ydGVyIHRpbWUgcmFuZ2UgKHdpdGhpbiAzMCBtaW51dGVzKS4KCjIuICByZWcuNjAgKEZvcmVjYXN0IGRlbGF5IHdpdGhpbiA2MCBtaW51dGVzKQoKLSAgIFNvbWUgbGFnIHZhcmlhYmxlcyBvZiBzaG9ydGVyIHRpbWUgKHN1Y2ggYXMgbGFnNDVtaW4pIGFyZSBvbWl0dGVkLCBhbmQgbW9yZSBhdHRlbnRpb24gaXMgcGFpZCB0byBsYWcgdmFyaWFibGVzIG9mIG1vcmUgdGhhbiAxIGhvdXIsIHN1Y2ggYXMgbGFnMWgzMG1pbiwgbGFnMmgsIGxhZzJoMzBtaW4sIGV0Yy4KCi0gICBTaW1wbGlmaWVkIHNpdGUgbGFnIHZhcmlhYmxlcywgaW5jbHVkaW5nIG9ubHkgbGFnczVzdGF0aW9uIGFuZCBsYWdzNnN0YXRpb24uCgotICAgSXQgaXMgc3VpdGFibGUgZm9yIGFuYWx5emluZyBwcmVkaWN0aW9ucyBvZiBtZWRpdW0gdGltZSByYW5nZSAod2l0aGluIDYwIG1pbnV0ZXMpIGRlbGF5cy4KCjMuICByZWcuOTAgKFByZWRpY3QgZGVsYXlzIHdpdGhpbiA5MCBtaW51dGVzKQoKLSAgIEZvY3VzIG9uIGxvbmdlciB0aW1lIHJhbmdlIGxhZyB2YXJpYWJsZXMsIHN1Y2ggYXMgbGFnMWgzMG1pbiwgbGFnMmgsIGxhZzNoLCBhbmQgcmVtb3ZlIHNob3J0IHRpbWUgbGFnIHZhcmlhYmxlcyAoc3VjaCBhcyBsYWc0NW1pbikuCgotICAgT25seSBvbmUgc2l0ZSBsYWcgdmFyaWFibGUsIGxhZ3M2c3RhdGlvbiwgaXMgcmV0YWluZWQuCgotICAgU3VpdGFibGUgZm9yIGFuYWx5emluZyBwcmVkaWN0aW9ucyBvZiBsb25nIHRpbWUgcmFuZ2VzICh3aXRoaW4gOTAgbWludXRlcykuCgpgYGB7cn0KZGVsYXkuVHJhaW4gPC0gZmlsdGVyKHJpZGUucGFuZWxfc3RhdGlvbiwgd2VlayA8PSAxMSkKZGVsYXkuVGVzdCA8LSBmaWx0ZXIocmlkZS5wYW5lbF9zdGF0aW9uLCB3ZWVrID4gMTEpCgoKcmVnLjMwIDwtIAogIGxtKGRlbGF5X21pbnV0ZXMgfiBmcm9tICsgdG8gKyB3ZWVrZW5kICsgVGVtcGVyYXR1cmUgKyBQcmVjaXBpdGF0aW9uICsgbGFnNDVtaW4gCiAgICAgKyBsYWcxaCArIGxhZzFoMTVtaW4gKyBsYWcxaDMwbWluICsgbGFnMWg0NW1pbiArIGxhZzJoICsgbGFnMmgxNW1pbiArIGxhZzJoMzBtaW4gKyAKICAgICAgIGxhZzJoNDVtaW4gKyBsYWczaCAKICAgICArIGxhZ3Mzc3RhdGlvbisgbGFnczRzdGF0aW9uKyBsYWdzNXN0YXRpb24gKyBzdG9wX3NlcXVlbmNlICAsIAogICAgIGRhdGE9ZGVsYXkuVHJhaW4pCgpyZWcuNjAgPC0gCiAgbG0oZGVsYXlfbWludXRlcyB+ICBmcm9tICsgdG8gKyB3ZWVrZW5kICsgVGVtcGVyYXR1cmUgKyBQcmVjaXBpdGF0aW9uIAogICAgKyBsYWcxaCArIGxhZzFoMTVtaW4gKyBsYWcxaDMwbWluICsgbGFnMWg0NW1pbiArIGxhZzJoICsgbGFnMmgxNW1pbiArIGxhZzJoMzBtaW4gKyBsYWcyaDQ1bWluICsgbGFnM2ggKyBsYWdzNXN0YXRpb24gKyBsYWdzNnN0YXRpb24gKyBzdG9wX3NlcXVlbmNlICwgCiAgICAgZGF0YT1kZWxheS5UcmFpbikKCnJlZy45MCA8LSAKICBsbShkZWxheV9taW51dGVzIH4gIGZyb20gKyB0byAgKyB3ZWVrZW5kICsgVGVtcGVyYXR1cmUgKyBQcmVjaXBpdGF0aW9uIAogICAgKyBsYWcxaDMwbWluICsgbGFnMWg0NW1pbiArIGxhZzJoICsgbGFnMmgxNW1pbiArIGxhZzJoMzBtaW4gKyBsYWcyaDQ1bWluICsgbGFnM2grIGxhZ3M2c3RhdGlvbiArIHN0b3Bfc2VxdWVuY2UgLCAKICAgICBkYXRhPWRlbGF5LlRyYWluKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQpkZWxheS5UZXN0LndlZWtOZXN0IDwtIAogICBkZWxheS5UZXN0ICU+JQogIG5lc3QoLXdlZWspIAoKbW9kZWxfcHJlZCA8LSBmdW5jdGlvbihkYXQsIGZpdCl7CiAgIHByZWQgPC0gcHJlZGljdChmaXQsIG5ld2RhdGEgPSBkYXQpfQpgYGAKClRoZSBCYXIgY2hhcnRzIGJlbG93IGlsbHVzdHJhdGVzIHRoZSBNQUUgdmFsdWVzIGZvciB0aGUgVGhyZWUgbW9kZWxzLiBJdCBkaXNwbGF5cyB0aGUgaGlnaGVzdCBNQUUgdmFsdWUgaW4gdGhlIDkwIG1pbiBkZWxheSBtb2RlbCwgYW5kIHRoZSBsb3dlc3QgTUFFIHZhbHVlIGluIHRoZSAzMC1taW4gZGVsYXkgbW9kZWwuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIDMwLW1pbnV0ZSBtb2RlbCBpcyB0aGUgbW9zdCBhY2N1cmF0ZSBhbW9uZyB0aGUgdGhyZWUuCgpgYGB7ciwgd2FybmluZz1GQUxTRX0Kd2Vla19wcmVkaWN0aW9ucyA8LSAKICBkZWxheS5UZXN0LndlZWtOZXN0ICU+JSAKICAgICAgICBtdXRhdGUobW9kLjMwID0gbWFwKC54ID0gZGF0YSwgZml0ID0gcmVnLjMwLCAuZiA9IG1vZGVsX3ByZWQpLAogICAgICAgICAgIG1vZC42MCA9IG1hcCgueCA9IGRhdGEsIGZpdCA9IHJlZy42MCwgLmYgPSBtb2RlbF9wcmVkKSwKICAgICAgICAgICBtb2QuOTAgPSBtYXAoLnggPSBkYXRhLCBmaXQgPSByZWcuOTAsIC5mID0gbW9kZWxfcHJlZCksCiAgICAgICAgICAgKSAlPiUgCiAgICBnYXRoZXIoUmVncmVzc2lvbiwgUHJlZGljdGlvbiwgLWRhdGEsIC13ZWVrKSAlPiUKICAgIG11dGF0ZShPYnNlcnZlZCA9IG1hcChkYXRhLCBwdWxsLCBkZWxheV9taW51dGVzKSwKICAgICAgICAgICBBYnNvbHV0ZV9FcnJvciA9IG1hcDIoT2JzZXJ2ZWQsIFByZWRpY3Rpb24sICB+IGFicygueCAtIC55KSksCiAgICAgICAgICAgTUFFID0gbWFwX2RibChBYnNvbHV0ZV9FcnJvciwgbWVhbiwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICBzZF9BRSA9IG1hcF9kYmwoQWJzb2x1dGVfRXJyb3IsIHNkLCBuYS5ybSA9IFRSVUUpKQoKd2Vla19wcmVkaWN0aW9ucyAlPiUKICBkcGx5cjo6c2VsZWN0KHdlZWssIFJlZ3Jlc3Npb24sIE1BRSkgJT4lCiAgZ2F0aGVyKFZhcmlhYmxlLCBNQUUsIC1SZWdyZXNzaW9uLCAtd2VlaykgJT4lCiAgZ2dwbG90KGFlcyh3ZWVrLCBNQUUpKSArIAogICAgZ2VvbV9iYXIoYWVzKGZpbGwgPSBSZWdyZXNzaW9uKSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBzdGF0PSJpZGVudGl0eSIpICsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGU1KSArCiAgICBsYWJzKHRpdGxlID0gIk1lYW4gQWJzb2x1dGUgRXJyb3JzIGJ5IG1vZGVsIHNwZWNpZmljYXRpb24gYW5kIHdlZWsiKSArCiAgcGxvdFRoZW1lCmBgYAoKVGhlIHRpbWUgc2VyaWVzIHBsb3QgYmVsb3cgc2hvd3MgdGhlIHByZWRpY3RlZCBhbmQgb2JzZXJ2ZWQgbWVhbiBkZWxheS4gT3ZlcmFsbCwgdGhlIG1vZGVscyB0ZW5kIHRvIHVuZGVyLXByZWRpY3QgdGhlIG9ic2VydmVkIHZhbHVlcy4gQW1vbmcgYWxsIHJlZ3Jlc3Npb24gbW9kZWxzLCB0aGUgMzAtbWludXRlIG1vZGVsIGlzIHRoZSBtb3N0IGFjY3VyYXRlLCBjbG9zZWx5IGNhcHR1cmluZyB0aGUgb2JzZXJ2ZWQgZGVsYXkgcGF0dGVybnMuIFRoZSBsb25nZXIgdGltZSBwcmVkaWN0aW9uIChzdWNoIGFzIDYwIGFuZCA5MCBtaW4gbW9kZWwpIHR5cGljYWxseSBpbnRyb2R1Y2UgZ3JlYXRlciB1bmNlcnRhaW50eSwgc28gdGhlIGFjY3VyYWN5IGRlY3JlYXNlIHdoaWxlIHRoZSBwcmVkaWN0aW9uIGhvcml6b24gaW5jcmVhc2VzICg2MCBhbmQgOTAgbWludXRlcykuCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KZGVsYXkuVGVzdF81IDwtIGRlbGF5LlRlc3QgJT4lCiAgbXV0YXRlKHByZV81ID0gcHJlZGljdChyZWcuMzAsIG5ld2RhdGEgPSBkZWxheS5UZXN0KSwKICAgICAgICAgYWJvc3VsdGVfZXJyb3IgPSBhYnMocHJlXzUgLSBkZWxheV9taW51dGVzKSwKICAgICAgICAgTUFFID0gbWVhbihhYm9zdWx0ZV9lcnJvciwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgc2RfQUUgPSBzZChhYm9zdWx0ZV9lcnJvciwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgcGVyX2Vycm9yID0gKHByZV81IC0gZGVsYXlfbWludXRlcykgLyBkZWxheV9taW51dGVzLAogICAgICAgICBwZXJfZXJyb3IgPSBpZmVsc2UocGVyX2Vycm9yID09IEluZiwgMCwgcGVyX2Vycm9yKSwKICAgICAgICAgcGVyX2Vycm9yID0gaWZlbHNlKHBlcl9lcnJvciA9PSAtSW5mLCAwLCBwZXJfZXJyb3IpKSAlPiUKICByZW5hbWUobW9kXzMwID0gcHJlXzUpCgpkZWxheS5UZXN0XzYgPC0gZGVsYXkuVGVzdCU+JQogIG11dGF0ZShwcmVfNiA9IHByZWRpY3QocmVnLjYwLCBuZXdkYXRhID0gZGVsYXkuVGVzdCksCiAgICAgICAgIGFib3N1bHRlX2Vycm9yID0gYWJzKHByZV82IC0gZGVsYXlfbWludXRlcyksCiAgICAgICAgIE1BRSA9IG1lYW4oYWJvc3VsdGVfZXJyb3IsbmEucm0gPSBUUlVFKSwKICAgICAgICAgc2RfQUUgPSBzZChhYm9zdWx0ZV9lcnJvcixuYS5ybSA9IFRSVUUpLAogICAgICAgICBwZXJfZXJyb3IgPSAocHJlXzYgLSBkZWxheV9taW51dGVzKS9kZWxheV9taW51dGVzLAogICAgICAgICBwZXJfZXJyb3IgPSBpZmVsc2UocGVyX2Vycm9yID09IEluZiwwLHBlcl9lcnJvciksCiAgICAgICAgIHBlcl9lcnJvciA9IGlmZWxzZShwZXJfZXJyb3IgPT0gLUluZiwwLHBlcl9lcnJvcikpJT4lCiAgcmVuYW1lKG1vZF82MCA9IHByZV82KQoKZGVsYXkuVGVzdF83IDwtIGRlbGF5LlRlc3QlPiUKICBtdXRhdGUocHJlXzcgPSBwcmVkaWN0KHJlZy45MCwgbmV3ZGF0YSA9IGRlbGF5LlRlc3QpLAogICAgICAgICBhYm9zdWx0ZV9lcnJvciA9IGFicyhwcmVfNyAtIGRlbGF5X21pbnV0ZXMpLAogICAgICAgICBNQUUgPSBtZWFuKGFib3N1bHRlX2Vycm9yLG5hLnJtID0gVFJVRSksCiAgICAgICAgIHNkX0FFID0gc2QoYWJvc3VsdGVfZXJyb3IsbmEucm0gPSBUUlVFKSwKICAgICAgICAgcGVyX2Vycm9yID0gKHByZV83IC0gZGVsYXlfbWludXRlcykvZGVsYXlfbWludXRlcywKICAgICAgICAgcGVyX2Vycm9yID0gaWZlbHNlKHBlcl9lcnJvciA9PSBJbmYsMCxwZXJfZXJyb3IpLAogICAgICAgICBwZXJfZXJyb3IgPSBpZmVsc2UocGVyX2Vycm9yID09IC1JbmYsMCxwZXJfZXJyb3IpKSU+JQogIHJlbmFtZShtb2RfOTAgPSBwcmVfNykKCmdyaWQuYXJyYW5nZSgKZGVsYXkuVGVzdF81ICU+JQogIGRwbHlyOjpzZWxlY3QoaW50ZXJ2YWw2MCwgZnJvbSwgZGVsYXlfbWludXRlcywgbW9kXzMwKSAlPiUKICBnYXRoZXIoVmFyaWFibGUsIFZhbHVlLCAtaW50ZXJ2YWw2MCwgLWZyb20pICU+JQogIGdyb3VwX2J5KFZhcmlhYmxlLCBpbnRlcnZhbDYwKSAlPiUKICBzdW1tYXJpemUoVmFsdWUgPSBtZWFuKFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBnZ3Bsb3QoYWVzKGludGVydmFsNjAsIFZhbHVlLCBjb2xvdXIgPSBWYXJpYWJsZSkpICsgCiAgICBnZW9tX2xpbmUoc2l6ZSA9IDAuOSkgKwogICAgbGFicygKICAgICAgdGl0bGUgPSAiUHJlZGljdGVkL09ic2VydmVkIERlbGF5IFRpbWUgU2VyaWVzIiwgCiAgICAgIHN1YnRpdGxlID0gIjMwIE1pbnV0ZXMgUHJlLVByZWRpY3QiLCAgCiAgICAgIHggPSAiRGF5IiwgCiAgICAgIHkgPSAiTWVhbiBEZWxheSIKICAgICkgKwogICAgdGhlbWVfbWluaW1hbCgpLAoKZGVsYXkuVGVzdF82ICU+JQogIGRwbHlyOjpzZWxlY3QoaW50ZXJ2YWw2MCwgZnJvbSwgZGVsYXlfbWludXRlcywgbW9kXzYwKSAlPiUKICBnYXRoZXIoVmFyaWFibGUsIFZhbHVlLCAtaW50ZXJ2YWw2MCwgLWZyb20pICU+JQogIGdyb3VwX2J5KFZhcmlhYmxlLCBpbnRlcnZhbDYwKSAlPiUKICBzdW1tYXJpemUoVmFsdWUgPSBtZWFuKFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBnZ3Bsb3QoYWVzKGludGVydmFsNjAsIFZhbHVlLCBjb2xvdXIgPSBWYXJpYWJsZSkpICsgCiAgICBnZW9tX2xpbmUoc2l6ZSA9IDAuOSkgKwogICAgbGFicygKICAgICAgdGl0bGUgPSAiUHJlZGljdGVkL09ic2VydmVkIERlbGF5IFRpbWUgU2VyaWVzIiwgCiAgICAgIHN1YnRpdGxlID0gIjYwIE1pbnV0ZXMgUHJlLVByZWRpY3QiLCAgCiAgICAgIHggPSAiRGF5IiwgCiAgICAgIHkgPSAiTWVhbiBEZWxheSIKICAgICkgKwogICAgdGhlbWVfbWluaW1hbCgpLAoKZGVsYXkuVGVzdF83ICU+JQogIGRwbHlyOjpzZWxlY3QoaW50ZXJ2YWw2MCwgZnJvbSwgZGVsYXlfbWludXRlcywgbW9kXzkwKSAlPiUKICBnYXRoZXIoVmFyaWFibGUsIFZhbHVlLCAtaW50ZXJ2YWw2MCwgLWZyb20pICU+JQogIGdyb3VwX2J5KFZhcmlhYmxlLCBpbnRlcnZhbDYwKSAlPiUKICBzdW1tYXJpemUoVmFsdWUgPSBtZWFuKFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBnZ3Bsb3QoYWVzKGludGVydmFsNjAsIFZhbHVlLCBjb2xvdXIgPSBWYXJpYWJsZSkpICsgCiAgICBnZW9tX2xpbmUoc2l6ZSA9IDAuOSkgKwogICAgbGFicygKICAgICAgdGl0bGUgPSAiUHJlZGljdGVkL09ic2VydmVkIERlbGF5IFRpbWUgU2VyaWVzIiwgCiAgICAgIHN1YnRpdGxlID0gIjkwIE1pbnV0ZXMgUHJlLVByZWRpY3QiLCAgCiAgICAgIHggPSAiRGF5IiwgCiAgICAgIHkgPSAiTWVhbiBEZWxheSIKICAgICkgKwogICAgdGhlbWVfbWluaW1hbCgpLAogbmNvbD0xKQoKYGBgCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Kd2Vla19wcmVkaWN0aW9ucyAlPiUgCiAgICBtdXRhdGUoaW50ZXJ2YWwxNSA9IG1hcChkYXRhLCBwdWxsLCBpbnRlcnZhbDE1KSwKICAgICAgICAgICBmcm9tX2lkID0gbWFwKGRhdGEsIHB1bGwsIGZyb21faWQpLCAKICAgICAgICAgICBmcm9tX2xhdCA9IG1hcChkYXRhLCBwdWxsLCBmcm9tX2xhdCksIAogICAgICAgICAgIGZyb21fbG9uID0gbWFwKGRhdGEsIHB1bGwsIGZyb21fbG9uKSkgJT4lCiAgICBzZWxlY3QoaW50ZXJ2YWwxNSwgZnJvbV9pZCwgZnJvbV9sb24sIGZyb21fbGF0LCBPYnNlcnZlZCwgUHJlZGljdGlvbiwgUmVncmVzc2lvbikgJT4lCiAgICB1bm5lc3QoKSAlPiUKICBmaWx0ZXIoUmVncmVzc2lvbiA9PSAibW9kLjMwIikgJT4lCiAgZ3JvdXBfYnkoZnJvbV9pZCwgZnJvbV9sb24sIGZyb21fbGF0KSAlPiUKICBzdW1tYXJpemUoTUFFID0gbWVhbihhYnMoT2JzZXJ2ZWQtUHJlZGljdGlvbiksIG5hLnJtID0gVFJVRSkpICU+JQpnZ3Bsb3QoLikrCiAgZ2VvbV9zZihkYXRhID0gTkpfQ2Vuc3VzLCBjb2xvciA9ICJncmV5NTAiLCBmaWxsPSJncmV5NzAiKSsKICBnZW9tX3BvaW50KGFlcyh4ID0gZnJvbV9sb24sIHkgPSBmcm9tX2xhdCwgY29sb3IgPSBNQUUpLCAKICAgICAgICAgICAgIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bigKICAgIG5hbWUgPSAiTWVhbiBBYnNvbHV0ZSBFcnJvciIsCiAgICBjb2xvcnMgPSBjKCJsaWdodHllbGxvdyIsICJyZWQiKQogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCkgIyBVc2UgYSBzaW5nbGUgbGVnZW5kIGd1aWRlCiAgKSArCiAgeWxpbShtaW4obWVyZ2VkX2RhdGFzZXQkZnJvbV9sYXQpLCBtYXgobWVyZ2VkX2RhdGFzZXQkZnJvbV9sYXQpKSsKICB4bGltKG1pbihtZXJnZWRfZGF0YXNldCRmcm9tX2xvbiksIG1heChtZXJnZWRfZGF0YXNldCRmcm9tX2xvbikpKwogIGxhYnModGl0bGU9Ik1lYW4gQWJzIEVycm9yLCAgTW9kZWwgMzAgbWluIikrCiAgbWFwVGhlbWUKCgp3ZWVrX3ByZWRpY3Rpb25zICU+JSAKICAgIG11dGF0ZShpbnRlcnZhbDE1ID0gbWFwKGRhdGEsIHB1bGwsIGludGVydmFsMTUpLAogICAgICAgICAgIGZyb21faWQgPSBtYXAoZGF0YSwgcHVsbCwgZnJvbV9pZCksIAogICAgICAgICAgIGZyb21fbGF0ID0gbWFwKGRhdGEsIHB1bGwsIGZyb21fbGF0KSwgCiAgICAgICAgICAgZnJvbV9sb24gPSBtYXAoZGF0YSwgcHVsbCwgZnJvbV9sb24pKSAlPiUKICAgIHNlbGVjdChpbnRlcnZhbDE1LCBmcm9tX2lkLCBmcm9tX2xvbiwgZnJvbV9sYXQsIE9ic2VydmVkLCBQcmVkaWN0aW9uLCBSZWdyZXNzaW9uKSAlPiUKICAgIHVubmVzdCgpICU+JQogIGZpbHRlcihSZWdyZXNzaW9uID09ICJtb2QuNjAiKSAlPiUKICBncm91cF9ieShmcm9tX2lkLCBmcm9tX2xvbiwgZnJvbV9sYXQpICU+JQogIHN1bW1hcml6ZShNQUUgPSBtZWFuKGFicyhPYnNlcnZlZC1QcmVkaWN0aW9uKSwgbmEucm0gPSBUUlVFKSkgJT4lCmdncGxvdCguKSsKICBnZW9tX3NmKGRhdGEgPSBOSl9DZW5zdXMsIGNvbG9yID0gImdyZXk1MCIsIGZpbGw9ImdyZXk3MCIpKwogIGdlb21fcG9pbnQoYWVzKHggPSBmcm9tX2xvbiwgeSA9IGZyb21fbGF0LCBjb2xvciA9IE1BRSksIAogICAgICAgICAgICAgZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGFscGhhID0gMC44KSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKAogICAgbmFtZSA9ICJNZWFuIEFic29sdXRlIEVycm9yIiwKICAgIGNvbG9ycyA9IGMoImxpZ2h0eWVsbG93IiwgInJlZCIpCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoKSAjIFVzZSBhIHNpbmdsZSBsZWdlbmQgZ3VpZGUKICApICsKICB5bGltKG1pbihtZXJnZWRfZGF0YXNldCRmcm9tX2xhdCksIG1heChtZXJnZWRfZGF0YXNldCRmcm9tX2xhdCkpKwogIHhsaW0obWluKG1lcmdlZF9kYXRhc2V0JGZyb21fbG9uKSwgbWF4KG1lcmdlZF9kYXRhc2V0JGZyb21fbG9uKSkrCiAgbGFicyh0aXRsZT0iTWVhbiBBYnMgRXJyb3IsICBNb2RlbCA2MCBtaW4iKSsKICBtYXBUaGVtZQoKd2Vla19wcmVkaWN0aW9ucyAlPiUgCiAgICBtdXRhdGUoaW50ZXJ2YWwxNSA9IG1hcChkYXRhLCBwdWxsLCBpbnRlcnZhbDE1KSwKICAgICAgICAgICBmcm9tX2lkID0gbWFwKGRhdGEsIHB1bGwsIGZyb21faWQpLCAKICAgICAgICAgICBmcm9tX2xhdCA9IG1hcChkYXRhLCBwdWxsLCBmcm9tX2xhdCksIAogICAgICAgICAgIGZyb21fbG9uID0gbWFwKGRhdGEsIHB1bGwsIGZyb21fbG9uKSkgJT4lCiAgICBzZWxlY3QoaW50ZXJ2YWwxNSwgZnJvbV9pZCwgZnJvbV9sb24sIGZyb21fbGF0LCBPYnNlcnZlZCwgUHJlZGljdGlvbiwgUmVncmVzc2lvbikgJT4lCiAgICB1bm5lc3QoKSAlPiUKICBmaWx0ZXIoUmVncmVzc2lvbiA9PSAibW9kLjkwIikgJT4lCiAgZ3JvdXBfYnkoZnJvbV9pZCwgZnJvbV9sb24sIGZyb21fbGF0KSAlPiUKICBzdW1tYXJpemUoTUFFID0gbWVhbihhYnMoT2JzZXJ2ZWQtUHJlZGljdGlvbiksIG5hLnJtID0gVFJVRSkpICU+JQpnZ3Bsb3QoLikrCiAgZ2VvbV9zZihkYXRhID0gTkpfQ2Vuc3VzLCBjb2xvciA9ICJncmV5NTAiLCBmaWxsPSJncmV5NzAiKSsKICBnZW9tX3BvaW50KGFlcyh4ID0gZnJvbV9sb24sIHkgPSBmcm9tX2xhdCwgY29sb3IgPSBNQUUpLCAKICAgICAgICAgICAgIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bigKICAgIG5hbWUgPSAiTWVhbiBBYnNvbHV0ZSBFcnJvciIsCiAgICBjb2xvcnMgPSBjKCJsaWdodHllbGxvdyIsICJyZWQiKQogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCkgIyBVc2UgYSBzaW5nbGUgbGVnZW5kIGd1aWRlCiAgKSArCiAgeWxpbShtaW4obWVyZ2VkX2RhdGFzZXQkZnJvbV9sYXQpLCBtYXgobWVyZ2VkX2RhdGFzZXQkZnJvbV9sYXQpKSsKICB4bGltKG1pbihtZXJnZWRfZGF0YXNldCRmcm9tX2xvbiksIG1heChtZXJnZWRfZGF0YXNldCRmcm9tX2xvbikpKwogIGxhYnModGl0bGU9Ik1lYW4gQWJzIEVycm9yLCAgTW9kZWwgOTAgbWluIikrCiAgbWFwVGhlbWUKCmBgYAoKVGhlIG1hcHMgYmVsb3cgcHJlc2VudCB0aGUgTUFFIChNZWFuIEFic29sdXRlIEVycm9yKSB2YWx1ZXMgZm9yIHRocmVlIGRpZmZlcmVudCBtb2RlbHMuIEFzIG9ic2VydmVkLCB0aGUgc291dGhlcm4gc3RhdGlvbnMgZXhoaWJpdCByZWxhdGl2ZWx5IGhpZ2hlciBNQUUgdmFsdWVzIGNvbXBhcmVkIHRvIG90aGVyIHJlZ2lvbnMsIGluZGljYXRpbmcgZ3JlYXRlciBwcmVkaWN0aW9uIGVycm9ycyBpbiB0aGVzZSBhcmVhcy4gTW9yZW92ZXIsIHRoZSBtYXBzIGJlbG93IHRoYXQgc3RpbGwgaWxsdXN0cmF0ZXMgdGhlIDMwLW1pbiBtb2RlbCBpcyB0aGUgbW9zdCBhY2N1cmF0ZSBwcmVkaWN0aW9ucywgd2l0aCBzbWFsbGVyIGFuZCBtb3JlIGxvY2FsaXplZCBlcnJvcnMuCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KIyBDb21iaW5lIHRoZSBkYXRhIGZvciBhbGwgbW9kZWxzIGludG8gb25lIGRhdGEgZnJhbWUKYWxsX21vZGVsc19kYXRhIDwtIHdlZWtfcHJlZGljdGlvbnMgJT4lCiAgbXV0YXRlKGludGVydmFsMTUgPSBtYXAoZGF0YSwgcHVsbCwgaW50ZXJ2YWwxNSksCiAgICAgICAgIGZyb21faWQgPSBtYXAoZGF0YSwgcHVsbCwgZnJvbV9pZCksIAogICAgICAgICBmcm9tX2xhdCA9IG1hcChkYXRhLCBwdWxsLCBmcm9tX2xhdCksIAogICAgICAgICBmcm9tX2xvbiA9IG1hcChkYXRhLCBwdWxsLCBmcm9tX2xvbikpICU+JQogIHNlbGVjdChpbnRlcnZhbDE1LCBmcm9tX2lkLCBmcm9tX2xvbiwgZnJvbV9sYXQsIE9ic2VydmVkLCBQcmVkaWN0aW9uLCBSZWdyZXNzaW9uKSAlPiUKICB1bm5lc3QoKSAlPiUKICBmaWx0ZXIoUmVncmVzc2lvbiAlaW4lIGMoIm1vZC4zMCIsICJtb2QuNjAiLCAibW9kLjkwIikpICU+JSAjIEluY2x1ZGUgb25seSB0aGUgbW9kZWxzIG9mIGludGVyZXN0CiAgZ3JvdXBfYnkoZnJvbV9pZCwgZnJvbV9sb24sIGZyb21fbGF0LCBSZWdyZXNzaW9uKSAlPiUKICBzdW1tYXJpemUoTUFFID0gbWVhbihhYnMoT2JzZXJ2ZWQgLSBQcmVkaWN0aW9uKSwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgbXV0YXRlKE1vZGVsID0gY2FzZV93aGVuKAogICAgUmVncmVzc2lvbiA9PSAibW9kLjMwIiB+ICIzMCBtaW4iLAogICAgUmVncmVzc2lvbiA9PSAibW9kLjYwIiB+ICI2MCBtaW4iLAogICAgUmVncmVzc2lvbiA9PSAibW9kLjkwIiB+ICI5MCBtaW4iCiAgKSkKCiMgUGxvdCB3aXRoIGZhY2V0X3dyYXAKZ2dwbG90KGFsbF9tb2RlbHNfZGF0YSkgKwogIGdlb21fc2YoZGF0YSA9IE5KX0NlbnN1cywgY29sb3IgPSAiZ3JleTUwIiwgZmlsbCA9ICJncmV5NzAiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IGZyb21fbG9uLCB5ID0gZnJvbV9sYXQsIGNvbG9yID0gTUFFKSwgCiAgICAgICAgICAgICBmaWxsID0gInRyYW5zcGFyZW50IiwgYWxwaGEgPSAwLjgpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudG4obmFtZSA9ICJNZWFuIEFic29sdXRlIEVycm9yIiwgY29sb3JzID0gYygibGlnaHR5ZWxsb3ciLCAicmVkIikpICsKICBmYWNldF93cmFwKH5Nb2RlbCkgKwogIHlsaW0obWluKG1lcmdlZF9kYXRhc2V0JGZyb21fbGF0KSwgbWF4KG1lcmdlZF9kYXRhc2V0JGZyb21fbGF0KSkgKwogIHhsaW0obWluKG1lcmdlZF9kYXRhc2V0JGZyb21fbG9uKSwgbWF4KG1lcmdlZF9kYXRhc2V0JGZyb21fbG9uKSkgKwogIGxhYnModGl0bGUgPSAiTWVhbiBBYnNvbHV0ZSBFcnJvciBieSBNb2RlbCIpICsKICBtYXBUaGVtZQoKYGBgCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Kd2Vla19wcmVkaWN0aW9ucyAlPiUgCiAgICBtdXRhdGUoaW50ZXJ2YWw2MCA9IG1hcChkYXRhLCBwdWxsLCBpbnRlcnZhbDYwKSwKICAgICAgICAgICBmcm9tX2lkID0gbWFwKGRhdGEsIHB1bGwsIGZyb21faWQpLCAKICAgICAgICAgICBmcm9tX2xhdGl0dWRlID0gbWFwKGRhdGEsIHB1bGwsIGZyb21fbGF0KSwgCiAgICAgICAgICAgZnJvbV9sb25naXR1ZGUgPSBtYXAoZGF0YSwgcHVsbCwgZnJvbV9sb24pLAogICAgICAgICAgIGRvdHcgPSBtYXAoZGF0YSwgcHVsbCwgZG90dykpICU+JQogICAgc2VsZWN0KGludGVydmFsNjAsIGZyb21faWQsIGZyb21fbG9uZ2l0dWRlLCAKICAgICAgICAgICBmcm9tX2xhdGl0dWRlLCBPYnNlcnZlZCwgUHJlZGljdGlvbiwgUmVncmVzc2lvbiwKICAgICAgICAgICBkb3R3KSAlPiUKICAgIHVubmVzdCgpICU+JQogIGZpbHRlcihSZWdyZXNzaW9uID09ICJtb2QuMzAiKSU+JQogIG11dGF0ZSh3ZWVrZW5kID0gaWZlbHNlKGRvdHcgJWluJSBjKCJTdW4iLCAiU2F0IiksICJXZWVrZW5kIiwgIldlZWtkYXkiKSwKICAgICAgICAgIHRpbWVfb2ZfZGF5ID0gY2FzZV93aGVuKGhvdXIoaW50ZXJ2YWw2MCkgPCA3IHwgaG91cihpbnRlcnZhbDYwKSA+IDE4IH4gIk92ZXJuaWdodCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIoaW50ZXJ2YWw2MCkgPj0gNyAmIGhvdXIoaW50ZXJ2YWw2MCkgPCAxMCB+ICJBTSBSdXNoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91cihpbnRlcnZhbDYwKSA+PSAxMCAmIGhvdXIoaW50ZXJ2YWw2MCkgPCAxNSB+ICJNaWQtRGF5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91cihpbnRlcnZhbDYwKSA+PSAxNSAmIGhvdXIoaW50ZXJ2YWw2MCkgPD0gMTggfiAiUE0gUnVzaCIpKSU+JQogIGdncGxvdCgpKwogIGdlb21fcG9pbnQoYWVzKHg9IE9ic2VydmVkLCB5ID0gUHJlZGljdGlvbikpKwogICAgZ2VvbV9zbW9vdGgoYWVzKHg9IE9ic2VydmVkLCB5PSBQcmVkaWN0aW9uKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikrCiAgICBnZW9tX2FibGluZShzbG9wZSA9IDEsIGludGVyY2VwdCA9IDApKwogIGZhY2V0X2dyaWQodGltZV9vZl9kYXl+d2Vla2VuZCkrCiAgbGFicyh0aXRsZT0iT2JzZXJ2ZWQgdnMgUHJlZGljdGVkIiwKICAgICAgIHg9Ik9ic2VydmVkIGRlbGF5IHRpbWUiLCAKICAgICAgIHk9IlByZWRpY3RlZCBkZWxheSB0aW1lIikrCiAgcGxvdFRoZW1lCmBgYAoKVGhlIG1hcHMgYmVsb3cgZGlzcGxheSB0aGUgZGlzdHJpYnV0aW9uIG9mIE1BRSB2YWx1ZXMgZm9yIE5KIHRyYW5zaXQgc3RhdGlvbnMgZHVyaW5nIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMgb24gd2Vla2RheXMgYW5kIHdlZWtlbmRzIHVzaW5nIHRoZSAzMC1taW51dGUgbW9kZWwuIE92ZXJhbGwsIHdlZWtlbmRzIGV4aGliaXQgcmVsYXRpdmVseSBoaWdoZXIgTUFFIHZhbHVlcyBjb21wYXJlZCB0byB3ZWVrZGF5cy4gTWVhbndoaWxlLCB0aGUgbW9kZWwgcGVyZm9ybXMgYmV0dGVyIGR1cmluZyB3ZWVrZGF5cywgYXMgaW5kaWNhdGVkIGJ5IGxvd2VyIE1BRSB2YWx1ZXMgYWNyb3NzIG1vc3Qgc3RhdGlvbnMgYW5kIHRpbWUgcGVyaW9kcy4KCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9MTIsIG1lc3NhZ2U9RkFMU0V9CndlZWtfcHJlZGljdGlvbnMgJT4lIAogICAgbXV0YXRlKGludGVydmFsNjAgPSBtYXAoZGF0YSwgcHVsbCwgaW50ZXJ2YWw2MCksCiAgICAgICAgICAgZnJvbV9pZCA9IG1hcChkYXRhLCBwdWxsLCBmcm9tX2lkKSwgCiAgICAgICAgICAgZnJvbV9sYXQgPSBtYXAoZGF0YSwgcHVsbCwgZnJvbV9sYXQpLCAKICAgICAgICAgICBmcm9tX2xvbiA9IG1hcChkYXRhLCBwdWxsLCBmcm9tX2xvbiksCiAgICAgICAgICAgZG90dyA9IG1hcChkYXRhLCBwdWxsLCBkb3R3KSkgJT4lCiAgICBzZWxlY3QoaW50ZXJ2YWw2MCwgZnJvbV9pZCwgZnJvbV9sb24sIAogICAgICAgICAgIGZyb21fbGF0LCBPYnNlcnZlZCwgUHJlZGljdGlvbiwgUmVncmVzc2lvbiwKICAgICAgICAgICBkb3R3KSAlPiUKICAgIHVubmVzdCgpICU+JQogIGZpbHRlcihSZWdyZXNzaW9uID09ICJtb2QuMzAiKSU+JQogIG11dGF0ZSh3ZWVrZW5kID0gaWZlbHNlKGRvdHcgJWluJSBjKCJTdW4iLCAiU2F0IiksICJXZWVrZW5kIiwgIldlZWtkYXkiKSwKICAgICAgICAgdGltZV9vZl9kYXkgPSBjYXNlX3doZW4oaG91cihpbnRlcnZhbDYwKSA8IDcgfCBob3VyKGludGVydmFsNjApID4gMTggfiAiT3Zlcm5pZ2h0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91cihpbnRlcnZhbDYwKSA+PSA3ICYgaG91cihpbnRlcnZhbDYwKSA8IDEwIH4gIkFNIFJ1c2giLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyKGludGVydmFsNjApID49IDEwICYgaG91cihpbnRlcnZhbDYwKSA8IDE1IH4gIk1pZC1EYXkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyKGludGVydmFsNjApID49IDE1ICYgaG91cihpbnRlcnZhbDYwKSA8PSAxOCB+ICJQTSBSdXNoIikpICU+JQogIGdyb3VwX2J5KGZyb21faWQsIHdlZWtlbmQsIHRpbWVfb2ZfZGF5LCBmcm9tX2xvbiwgZnJvbV9sYXQpICU+JQogIHN1bW1hcml6ZShNQUUgPSBtZWFuKGFicyhPYnNlcnZlZC1QcmVkaWN0aW9uKSwgbmEucm0gPSBUUlVFKSklPiUKICBnZ3Bsb3QoLikrCiAgZ2VvbV9zZihkYXRhID0gTkpfQ2Vuc3VzLCBjb2xvciA9ICJ3aGl0ZSIpKwogICBnZW9tX3BvaW50KGFlcyh4ID0gZnJvbV9sb24sIHkgPSBmcm9tX2xhdCwgY29sb3IgPSBNQUUpLCAKICAgICAgICAgICAgIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBhbHBoYSA9IDAuNSwgc2l6ZSA9IDMpICsKICBzY2FsZV9jb2xvdXJfdmlyaWRpcyhkaXJlY3Rpb24gPSAtMSwKICBkaXNjcmV0ZSA9IEZBTFNFLCBvcHRpb24gPSAiRSIpICsKICB5bGltKG1pbihkYXRfY2Vuc3VzJGZyb21fbGF0KSwgbWF4KGRhdF9jZW5zdXMkZnJvbV9sYXQpKSsKICB4bGltKG1pbihkYXRfY2Vuc3VzJGZyb21fbG9uKSwgbWF4KGRhdF9jZW5zdXMkZnJvbV9sb24pKSsKICBmYWNldF9ncmlkKHdlZWtlbmR+dGltZV9vZl9kYXkpKwogIGxhYnModGl0bGU9Ik1lYW4gQWJzb2x1dGUgRXJyb3JzLCAzMCBtaW4gTW9kZWwiKSsKICBtYXBUaGVtZQpgYGAKCiMgQ29uY2x1c2lvbgoKQWxsIHRocmVlIG9mIG91ciBwcmVkaWN0aXZlIG1vZGVscyBjYW4gZG8gYSBkZWNlbnQgam9iIGF0IHByZWRpY3RpbmcgcG90ZW50aWFsIGRlbGF5cyBmb3IgTkogdHJhbnNpdCB0cmFpbnMgd2l0aCBhIE1BRSBvZiBsZXNzIHRoYW4gMTAgbWludXRlcy4gV2l0aCB0aGUgaGVscCBvZiB0aGUgbW9iaWxlIGFwcCwgcGVvcGxlIHdobyBjb21tdXRlIHRvIHdvcmsgb3Igc2Nob29sLCB0aG9zZSB3aG8gZnJlcXVlbnRseSB0cmF2ZWwgdXNpbmcgcHVibGljIHRyYW5zaXQsIGFuZCB0aG9zZSB3aXRoIGEgdGlnaHQgc2NoZWR1bGUgY2FuIGJlbmVmaXQgZnJvbSB0aGUgcmVsYXRpdmUgYWNjdXJhdGUgcHJlZGljdGVkIGRlbGF5IHRpbWUgcHJvdmlkZWQgYnkgb3VyIG1vZGVscy4gTm90IG9ubHkgY291bGQgdGhpcyBoZWxwIHRoZW0gc2F2ZSB0aW1lIGFuZCBzdGF5IGF3YXkgZnJvbSB1bmV4cGVjdGVkIGRlbGF5cywgYnV0IGl0IGNhbiBhbHNvIGhlbHAgdGhlbSB3aXRoIHRoZWlyIHRyYXZlbGluZyBiZWhhdmlvciB3aGlsZSBvZmZlcmluZyB0aGVtIHdpdGggYWx0ZXJuYXRpdmUgcGxhbnMuIFRvIG1ha2UgdGhlIGFuYWx5c2lzIGJldHRlciwgd2UgY2FuIGFsd2F5cyBpbmNsdWRlIG1vcmUgcmVsZXZhbnQgaW5mb3JtYXRpb24gYW5kIGZhY3RvcnMgdGhhdCBtaWdodCBhZmZlY3QgdHJhaW4gZGVsYXkgdGltZSBmb3IgYSBtb3JlIGFjY3VyYXRlIGFuZCBjb21wcmVoZW5zaXZlIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHByb2JsZW0gd2UgYXJlIGRlYWxpbmcgd2l0aC4gV2UgY2FuIGRpZyBkZWVwZXIgaW50byB0aGUgc3R1ZHkgYW5kIGFuYWx5emUgdGhlIGRlbGF5IHRpbWVzIGZvciBlYWNoIG9mIHRoZSBzdGF0aW9ucyB0byBmaW5kIGRlbGF5IHBhdHRlcm5zIHRoYXQgd2UgbWlnaHQgb3Zlcmxvb2tlZCB3aXRoIG91ciBtYWNybyBhcHByb2FjaC4gQW5vdGhlciB0aGluZyB3ZSBjYW4gZG8gaXMgdG8gaW5jbHVkZSBkYXRhIGZyb20gdGhlIGFkamFjZW50IGNpdGllc+KAmSB0cmFuc2l0IHN5c3RlbSB0byB1bmRlcnN0YW5kIGhvdyB0aGV5IGFmZmVjdCB0aGUgZGVsYXkgdGltZXMgaW4gTmV3IEplcnNleS4K